使用英语阅读

通过


在控制台应用程序中轮询

使用 ADO.NET 中的异步操作,可以在一个线程上启动耗时的数据库操作,同时在另一个线程上执行其他任务。 但在大多数情况下,最终会遇到这样的情况:在数据库操作完成之前,应用程序不应继续运行。 对于这种情况,一个有用的方法是轮询异步操作以确定操作是否已完成。

可以使用 IsCompleted 属性来确定操作是否已完成。

示例

以下控制台应用程序更新 AdventureWorks 示例数据库中的数据,异步完成其任务。 为了模拟长时间运行的进程,此示例在命令文本中插入一个 WAITFOR 语句。 通常,你不会尝试使命令运行速度变慢,但是在这种情况下,这样做可以更轻松地演示异步行为。

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 "..." + "Asynchronous Processing=true";
    }
}

请参阅