在主控台應用程式中輪詢 (ADO.NET)
更新: November 2007
ADO.NET 中的非同步作業可讓您在另一個執行緒上執行其他工作的同時,在一個執行緒上起始耗時的資料庫工作。不過,在大多數案例中,最後仍會形成資料庫作業若未完成,則應用程式將無法繼續的狀況。對於這些狀況,輪詢非同步作業以判定作業是否完成是很有用的。
您可使用 IsCompleted 屬性,查明作業是否已完成。
範例
下列主控台應用程式會更新 AdventureWorks 範例資料庫中的資料,且會非同步地執行其工作。為了模擬長期執行的處理序,此範例會將 WAITFOR 陳述式插入命令文字中。一般來說,您不會嘗試讓命令執行得較慢,但在此案例中這樣做會更容易示範非同步的行為。
[Visual Basic]
Imports System
Imports System.Data.SqlClient
Module Module1
Sub Main()
' The WAITFOR statement simply adds enough time to prove the
' asynchronous nature of the command.
Dim commandText As String = _
"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()
End Sub
Private Sub RunCommandAsynchronously( _
ByVal commandText As String, ByVal connectionString As String)
' 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 connection As New SqlConnection(connectionString)
Try
Dim count As Integer = 0
Dim command As New SqlCommand(commandText, connection)
connection.Open()
Dim result As IAsyncResult = _
command.BeginExecuteNonQuery()
While Not 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.
Threading.Thread.Sleep(100)
count += 1
End While
Console.WriteLine( _
"Command complete. Affected {0} rows.", _
command.EndExecuteNonQuery(result))
Catch ex As SqlException
Console.WriteLine("Error ({0}): {1}", _
ex.Number, ex.Message)
Catch ex As InvalidOperationException
Console.WriteLine("Error: {0}", ex.Message)
Catch ex As Exception
' You might want to pass these errors
' back out to the caller.
Console.WriteLine("Error: {0}", ex.Message)
End Try
End Using
End Sub
Private Function GetConnectionString() As String
' 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"
End Function
End Module
[C#]
using System;
using System.Data;
using System.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";
}
}