ADO.NET 中的非同步作業可讓您在一個執行緒上起始耗時的資料庫作業,同時在另一個執行緒上執行其他工作。 不過,在大部分情況下,您最後將會到達應用程式不應該繼續執行的時機點,直到資料庫作業完成為止。 在這種情況下,輪詢非同步作業以判斷作業是否已經完成會很有用。
您可以使用 IsCompleted 屬性來知道作業是否已經完成。
範例
下列主控台應用程式會更新 AdventureWorks 範例資料庫中的資料,且會非同步地執行其工作。 為了模擬長時間執行的程序,此範例會在命令文字中插入 WAITFOR 陳述式。 一般來說,您不會嘗試讓命令執行速度變慢,但在此案例中,這樣做可讓您更輕鬆地示範非同步行為。
using System;
using System.Data;
using Microsoft.Data.SqlClient;
class Class1
{
[STAThread]
static void Main()
{
// The WAITFOR statement simply adds enough time to
// prove the asynchronous nature of the command.
string commandText =
"UPDATE Production.Product SET ReorderPoint = " +
"ReorderPoint + 1 " +
"WHERE ReorderPoint Is Not Null;" +
"WAITFOR DELAY '0:0:3';" +
"UPDATE Production.Product SET ReorderPoint = " +
"ReorderPoint - 1 " +
"WHERE ReorderPoint Is Not Null";
RunCommandAsynchronously(
commandText, GetConnectionString());
Console.WriteLine("Press Enter to continue.");
Console.ReadLine();
}
private static void RunCommandAsynchronously(
string commandText, string connectionString)
{
// Given command text and connection string, asynchronously
// execute the specified command against the connection.
// For this example, the code displays an indicator as it's
// working, verifying the asynchronous behavior.
using (SqlConnection connection =
new SqlConnection(connectionString))
{
try
{
int count = 0;
SqlCommand command =
new SqlCommand(commandText, connection);
connection.Open();
IAsyncResult result =
command.BeginExecuteNonQuery();
while (!result.IsCompleted)
{
Console.WriteLine(
"Waiting ({0})", count++);
// Wait for 1/10 second, so the counter
// doesn't consume all available
// resources on the main thread.
System.Threading.Thread.Sleep(100);
}
Console.WriteLine(
"Command complete. Affected {0} rows.",
command.EndExecuteNonQuery(result));
}
catch (SqlException ex)
{
Console.WriteLine("Error ({0}): {1}",
ex.Number, ex.Message);
}
catch (InvalidOperationException ex)
{
Console.WriteLine("Error: {0}", ex.Message);
}
catch (Exception ex)
{
// You might want to pass these errors
// back out to the caller.
Console.WriteLine("Error: {0}", ex.Message);
}
}
}
private static string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
// If you have not included "Asynchronous Processing=true"
// in the connection string, the command will not be able
// to execute asynchronously.
return "Data Source=(local);Integrated Security=SSPI;" +
"Initial Catalog=AdventureWorks; " +
"Asynchronous Processing=true";
}
}