Skip to content

Commit db7572a

Browse files
committed
Merge branch 'try-activeissue-tests' of https://github.com/MichelZ/SqlClient into try-activeissue-tests
2 parents b7720df + d85ee61 commit db7572a

File tree

67 files changed

+2112
-3653
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+2112
-3653
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// <Snippet1>
2+
using System;
3+
using Microsoft.Data.SqlClient;
4+
5+
class Class1
6+
{
7+
static void Main()
8+
{
9+
// This is a simple example that demonstrates the usage of the
10+
// BeginExecuteReader functionality
11+
// The WAITFOR statement simply adds enough time to prove the
12+
// asynchronous nature of the command.
13+
string commandText =
14+
"WAITFOR DELAY '00:00:03';" +
15+
"SELECT LastName, FirstName FROM Person.Contact " +
16+
"WHERE LastName LIKE 'M%'";
17+
18+
RunCommandAsynchronously(commandText, GetConnectionString());
19+
20+
Console.WriteLine("Press ENTER to continue.");
21+
Console.ReadLine();
22+
}
23+
24+
private static void RunCommandAsynchronously(
25+
string commandText, string connectionString)
26+
{
27+
// Given command text and connection string, asynchronously execute
28+
// the specified command against the connection. For this example,
29+
// the code displays an indicator as it is working, verifying the
30+
// asynchronous behavior.
31+
using (SqlConnection connection = new SqlConnection(connectionString))
32+
{
33+
try
34+
{
35+
SqlCommand command = new SqlCommand(commandText, connection);
36+
37+
connection.Open();
38+
IAsyncResult result = command.BeginExecuteReader();
39+
40+
// Although it is not necessary, the following code
41+
// displays a counter in the console window, indicating that
42+
// the main thread is not blocked while awaiting the command
43+
// results.
44+
int count = 0;
45+
while (!result.IsCompleted)
46+
{
47+
count += 1;
48+
Console.WriteLine("Waiting ({0})", count);
49+
// Wait for 1/10 second, so the counter
50+
// does not consume all available resources
51+
// on the main thread.
52+
System.Threading.Thread.Sleep(100);
53+
}
54+
55+
using (SqlDataReader reader = command.EndExecuteReader(result))
56+
{
57+
DisplayResults(reader);
58+
}
59+
}
60+
catch (SqlException ex)
61+
{
62+
Console.WriteLine("Error ({0}): {1}", ex.Number, ex.Message);
63+
}
64+
catch (InvalidOperationException ex)
65+
{
66+
Console.WriteLine("Error: {0}", ex.Message);
67+
}
68+
catch (Exception ex)
69+
{
70+
// You might want to pass these errors
71+
// back out to the caller.
72+
Console.WriteLine("Error: {0}", ex.Message);
73+
}
74+
}
75+
}
76+
77+
private static void DisplayResults(SqlDataReader reader)
78+
{
79+
// Display the data within the reader.
80+
while (reader.Read())
81+
{
82+
// Display all the columns.
83+
for (int i = 0; i < reader.FieldCount; i++)
84+
{
85+
Console.Write("{0}\t", reader.GetValue(i));
86+
}
87+
Console.WriteLine();
88+
}
89+
}
90+
91+
private static string GetConnectionString()
92+
{
93+
// To avoid storing the connection string in your code,
94+
// you can retrieve it from a configuration file.
95+
96+
return "Data Source=(local);Integrated Security=true;" +
97+
"Initial Catalog=AdventureWorks";
98+
}
99+
}
100+
// </Snippet1>

doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1173,7 +1173,106 @@
11731173
The following console application starts the process of retrieving a data reader asynchronously. While waiting for the results, this simple application sits in a loop, investigating the <see cref="P:System.IAsyncResult.IsCompleted" /> property value. As soon as the process has completed, the code retrieves the <see cref="T:Microsoft.Data.SqlClient.SqlDataReader" /> and displays its contents.
11741174
</para>
11751175
<!-- SqlCommand_BeginExecuteReader -->
1176-
<!-- SAMPLE MISSING -->
1176+
<code language="c#">
1177+
using System;
1178+
using Microsoft.Data.SqlClient;
1179+
1180+
class Class1
1181+
{
1182+
static void Main()
1183+
{
1184+
// This is a simple example that demonstrates the usage of the
1185+
// BeginExecuteReader functionality
1186+
// The WAITFOR statement simply adds enough time to prove the
1187+
// asynchronous nature of the command.
1188+
string commandText =
1189+
"WAITFOR DELAY '00:00:03';" +
1190+
"SELECT LastName, FirstName FROM Person.Contact " +
1191+
"WHERE LastName LIKE 'M%'";
1192+
1193+
RunCommandAsynchronously(commandText, GetConnectionString());
1194+
1195+
Console.WriteLine("Press ENTER to continue.");
1196+
Console.ReadLine();
1197+
}
1198+
1199+
private static void RunCommandAsynchronously(
1200+
string commandText, string connectionString)
1201+
{
1202+
// Given command text and connection string, asynchronously execute
1203+
// the specified command against the connection. For this example,
1204+
// the code displays an indicator as it is working, verifying the
1205+
// asynchronous behavior.
1206+
using (SqlConnection connection = new SqlConnection(connectionString))
1207+
{
1208+
try
1209+
{
1210+
SqlCommand command = new SqlCommand(commandText, connection);
1211+
1212+
connection.Open();
1213+
IAsyncResult result = command.BeginExecuteReader();
1214+
1215+
// Although it is not necessary, the following code
1216+
// displays a counter in the console window, indicating that
1217+
// the main thread is not blocked while awaiting the command
1218+
// results.
1219+
int count = 0;
1220+
while (!result.IsCompleted)
1221+
{
1222+
count += 1;
1223+
Console.WriteLine("Waiting ({0})", count);
1224+
// Wait for 1/10 second, so the counter
1225+
// does not consume all available resources
1226+
// on the main thread.
1227+
System.Threading.Thread.Sleep(100);
1228+
}
1229+
1230+
using (SqlDataReader reader = command.EndExecuteReader(result))
1231+
{
1232+
DisplayResults(reader);
1233+
}
1234+
}
1235+
catch (SqlException ex)
1236+
{
1237+
Console.WriteLine("Error ({0}): {1}", ex.Number, ex.Message);
1238+
}
1239+
catch (InvalidOperationException ex)
1240+
{
1241+
Console.WriteLine("Error: {0}", ex.Message);
1242+
}
1243+
catch (Exception ex)
1244+
{
1245+
// You might want to pass these errors
1246+
// back out to the caller.
1247+
Console.WriteLine("Error: {0}", ex.Message);
1248+
}
1249+
}
1250+
}
1251+
1252+
private static void DisplayResults(SqlDataReader reader)
1253+
{
1254+
// Display the data within the reader.
1255+
while (reader.Read())
1256+
{
1257+
// Display all the columns.
1258+
for (int i = 0; i &lt; reader.FieldCount; i++)
1259+
{
1260+
Console.Write("{0}\t", reader.GetValue(i));
1261+
}
1262+
Console.WriteLine();
1263+
}
1264+
}
1265+
1266+
private static string GetConnectionString()
1267+
{
1268+
// To avoid storing the connection string in your code,
1269+
// you can retrieve it from a configuration file.
1270+
1271+
return "Data Source=(local);Integrated Security=true;" +
1272+
"Initial Catalog=AdventureWorks";
1273+
}
1274+
}
1275+
</code>
11771276
</example>
11781277
<exception cref="T:System.InvalidCastException">
11791278
<list type="bullet">

doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2853,6 +2853,39 @@
28532853
Any error returned by SQL Server that occurred while opening the connection.
28542854
</exception>
28552855
</OpenAsync>
2856+
<OpenAsyncWithOverrides>
2857+
<param name="overrides">
2858+
Options to override default connection open behavior.
2859+
</param>
2860+
<param name="cancellationToken">
2861+
The cancellation instruction.
2862+
</param>
2863+
<summary>
2864+
An asynchronous version of <see cref="M:Microsoft.Data.SqlClient.SqlConnection.Open" />, which opens a database connection with the property settings specified by the <see cref="P:Microsoft.Data.SqlClient.SqlConnection.ConnectionString" />. The cancellation token can be used to request that the operation be abandoned before the connection timeout elapses. Exceptions will be propagated via the returned Task. If the connection timeout time elapses without successfully connecting, the returned Task will be marked as faulted with an Exception. The implementation returns a Task without blocking the calling thread for both pooled and non-pooled connections.
2865+
</summary>
2866+
<returns>
2867+
A task representing the asynchronous operation.
2868+
</returns>
2869+
<remarks>
2870+
<para>
2871+
After calling <see cref="M:Microsoft.Data.SqlClient.SqlConnection.OpenAsync" />, <see cref="P:Microsoft.Data.SqlClient.SqlConnection.State" /> must return <see cref="F:System.Data.ConnectionState.Connecting" /> until the returned <see cref="T:System.Threading.Tasks.Task" /> is completed. Then, if the connection was successful, <see cref="P:Microsoft.Data.SqlClient.SqlConnection.State" /> must return <see cref="F:System.Data.ConnectionState.Open" />. If the connection fails, <see cref="P:Microsoft.Data.SqlClient.SqlConnection.State" /> must return <see cref="F:System.Data.ConnectionState.Closed" />.
2872+
</para>
2873+
<para>
2874+
A call to <see cref="M:Microsoft.Data.SqlClient.SqlConnection.Close" /> will attempt to cancel or close the corresponding <see cref="M:Microsoft.Data.SqlClient.SqlConnection.OpenAsync" /> call. For more information about asynchronous programming in the .NET Framework Data Provider for SQL Server, see <see href="/sql/connect/ado-net/asynchronous-programming">Asynchronous Programming</see>.
2875+
</para>
2876+
</remarks>
2877+
<exception cref="T:System.InvalidOperationException">
2878+
<para>
2879+
Calling <see cref="M:Microsoft.Data.SqlClient.SqlConnection.OpenAsync(Microsoft.Data.SqlClient.SqlConnectionOverrides, System.Threading.CancellationToken)" /> more than once for the same instance before task completion.
2880+
</para>
2881+
<para>
2882+
A connection was not available from the connection pool before the connection time out elapsed.
2883+
</para>
2884+
</exception>
2885+
<exception cref="T:Microsoft.Data.SqlClient.SqlException">
2886+
Any error returned by SQL Server that occurred while opening the connection.
2887+
</exception>
2888+
</OpenAsyncWithOverrides>
28562889
<PacketSize>
28572890
<summary>
28582891
Gets the size (in bytes) of network packets used to communicate with an instance of SQL Server.

eng/pipelines/common/templates/jobs/ci-code-coverage-job.yml

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -60,25 +60,51 @@ jobs:
6060
Get-ChildItem $(Build.SourcesDirectory)\coverageNetCore\ -Recurse -File -Filter *.coverage
6161
displayName: 'List coverageNetCore files [debug]'
6262
63-
- powershell: |
63+
- pwsh: |
6464
dotnet tool install --global dotnet-coverage
6565
66-
$files = Get-ChildItem $(Build.SourcesDirectory)\coverageNetFx\ -Recurse -File -Filter *.coverage
67-
# echo $files
68-
mkdir coverageNetFxXml
69-
$counter=0
70-
foreach ($file in $files) {
71-
& dotnet-coverage merge $file.FullName --output coverageNetFxXml\$((++$counter)).coveragexml --output-format xml
72-
}
66+
function MergeFiles {
67+
param(
68+
[string]$InputDirectoryPath,
69+
[string]$OutputDirectoryName
70+
)
71+
72+
$files = Get-ChildItem $InputDirectoryPath -Recurse -File -Filter *.coverage
73+
74+
# echo $files
75+
mkdir $OutputDirectoryName
76+
$counter=0
77+
78+
$toProcess = @()
79+
80+
foreach ($file in $files) {
81+
$toProcess += @{
82+
File = $file.FullName
83+
OutputFile = "$OutputDirectoryName\$counter.coveragexml"
84+
}
85+
86+
$counter++
87+
}
88+
89+
$jobs = @()
90+
foreach ($file in $toProcess){
91+
$jobs += Start-ThreadJob -ScriptBlock {
92+
$params = $using:file
93+
& dotnet-coverage merge $($params.File) --output $($params.OutputFile) --output-format xml
94+
}
95+
}
7396
74-
$files = Get-ChildItem $(Build.SourcesDirectory)\coverageNetCore\ -Recurse -File -Filter *.coverage
75-
# echo $files
76-
mkdir coverageNetCoreXml
77-
$counter=0
78-
foreach ($file in $files) {
79-
& dotnet-coverage merge $file.FullName --output coverageNetCoreXml\$((++$counter)).coveragexml --output-format xml
97+
Write-Host "Merging started..."
98+
Wait-Job -Job $jobs
99+
100+
foreach ($job in $jobs) {
101+
Receive-Job -Job $job -Wait -AutoRemoveJob
102+
}
80103
}
81104
105+
MergeFiles -InputDirectoryPath "$(Build.SourcesDirectory)\coverageNetFx\" -OutputDirectoryName "coverageNetFxXml"
106+
MergeFiles -InputDirectoryPath "$(Build.SourcesDirectory)\coverageNetCore\" -OutputDirectoryName "coverageNetCoreXml"
107+
82108
# dir coverageNetFxXml\
83109
# dir coverageNetCoreXml\
84110
@@ -95,14 +121,28 @@ jobs:
95121
dir coverageNetCoreXml\
96122
displayName: 'List converted files [debug]'
97123
98-
- script: |
124+
- pwsh: |
99125
dotnet tool install dotnet-reportgenerator-globaltool --tool-path tools
100126
101-
tools\reportgenerator "-reports:coverageNetFxXml\*.coveragexml" "-targetdir:coveragereportNetFx" "-reporttypes:Cobertura;" "-assemblyfilters:+microsoft.data.sqlclient.dll" "-sourcedirs:$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\netfx\src;$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\src" "-classfilters:+Microsoft.Data.*"
127+
$jobs = @()
128+
$jobs += Start-ThreadJob -ScriptBlock {
129+
& tools\reportgenerator "-reports:coverageNetFxXml\*.coveragexml" "-targetdir:coveragereportNetFx" "-reporttypes:Cobertura;" "-assemblyfilters:+microsoft.data.sqlclient.dll" "-sourcedirs:$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\netfx\src;$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\src" "-classfilters:+Microsoft.Data.*"
130+
}
131+
132+
$jobs += Start-ThreadJob -ScriptBlock {
133+
& tools\reportgenerator "-reports:coverageNetCoreXml\*.coveragexml" "-targetdir:coveragereportAddOns" "-reporttypes:Cobertura;" "-assemblyfilters:+microsoft.data.sqlclient.alwaysencrypted.azurekeyvaultprovider.dll" "-sourcedirs:$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\add-ons\AzureKeyVaultProvider" "-classfilters:+Microsoft.Data.*"
134+
}
135+
136+
$jobs += Start-ThreadJob -ScriptBlock {
137+
& tools\reportgenerator "-reports:coverageNetCoreXml\*.coveragexml" "-targetdir:coveragereportNetCore" "-reporttypes:Cobertura;" "-assemblyfilters:+microsoft.data.sqlclient.dll" "-sourcedirs:$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\netcore\src;$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\src" "-classfilters:+Microsoft.Data.*"
138+
}
102139
103-
tools\reportgenerator "-reports:coverageNetCoreXml\*.coveragexml" "-targetdir:coveragereportAddOns" "-reporttypes:Cobertura;" "-assemblyfilters:+microsoft.data.sqlclient.alwaysencrypted.azurekeyvaultprovider.dll" "-sourcedirs:$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\add-ons\AzureKeyVaultProvider" "-classfilters:+Microsoft.Data.*"
140+
Write-Host "Running ReportGenerator..."
141+
Wait-Job -Job $jobs
104142
105-
tools\reportgenerator "-reports:coverageNetCoreXml\*.coveragexml" "-targetdir:coveragereportNetCore" "-reporttypes:Cobertura;" "-assemblyfilters:+microsoft.data.sqlclient.dll" "-sourcedirs:$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\netcore\src;$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\src" "-classfilters:+Microsoft.Data.*"
143+
foreach ($job in $jobs) {
144+
Receive-Job -Job $job -Wait -AutoRemoveJob
145+
}
106146
displayName: 'Run ReportGenerator'
107147
108148
- task: PublishCodeCoverageResults@2

eng/pipelines/common/templates/jobs/ci-run-tests-job.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ parameters:
4747
type: boolean
4848
default: false
4949

50+
- name: enableX64Test
51+
type: boolean
52+
default: true
53+
5054
- name: testSet
5155
type: string
5256

@@ -205,6 +209,7 @@ jobs:
205209
${{ if ne(parameters.operatingSystem, 'Windows') }}:
206210
OSGroup: Unix
207211

212+
- ${{ if eq(parameters.enableX64Test, true) }}: # run native tests
208213
- template: ../steps/run-all-tests-step.yml@self # run tests
209214
parameters:
210215
debug: ${{ parameters.debug }}

eng/pipelines/common/templates/stages/ci-run-tests-stage.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ stages:
6565
${{ each x86TF in config.value.configProperties.x86TestTargetFrameworks }}:
6666
${{ if eq(x86TF, targetFramework) }}:
6767
enableX86Test: true
68+
enableX64Test: false
6869
- ${{ else }}: # .NET
6970
- ${{ each useManagedSNI in config.value.useManagedSNI }}:
7071
- template: ../jobs/ci-run-tests-job.yml@self
@@ -93,6 +94,7 @@ stages:
9394
${{ each x86TF in config.value.configProperties.x86TestTargetFrameworks }}:
9495
${{ if eq(x86TF, targetFramework) }}:
9596
enableX86Test: true
97+
enableX64Test: false
9698

9799
- ${{ if ne(length(parameters.postTestJobs), 0) }}:
98100
- stage: Post_Test

0 commit comments

Comments
 (0)