2

非同期クエリの実行を使用して、MS SQL サーバーから MySQL サーバーにデータを移動するアプリがあります。データは正常に移動しますが、RunAllTask​​s() メソッドの Task.WaitAll(tasks) 呼び出しは完了しません。

非同期タスクはすべて、PumpLocsAsync() のパターンに従います。MS SQL への呼び出しは、BeginExecuteReader を介して非同期的に呼び出されます。リーダーが結果を返すと、MySQL は正常に挿入します。

..

async Task PumpLocsAsync()
{
     using (var conn = new SqlConnection(SqlConnStr))
     using (var cn = new MySqlConnection(MysqlConnStr))
     using (var cmd = new SqlCommand())
     {
          cmd.Connection = conn;
          cmd.CommandText = "SELECT HERE";

          conn.Open();
          var handle = cmd.BeginExecuteReader();
          await Task.Factory.FromAsync(handle, (ar) =>
          {
               var rdr = cmd.EndExecuteReader(ar);
               var qry = @"INSERT HERE";

               cn.Open();
               using (var cmdm = new MySqlCommand(qry, cn))
               {
                   cmdm.CommandTimeout = MysqlCmdtimeout;
                   <PARAM SETUP HERE>
                   <COLUMN MAPPING HERE>

                   while (RetryUtility.RetryMethod<bool>(() => rdr.Read(), 3, 1000))
                   {
                       <LOADING PARAMS WITH BITS HERE>
                       RetryUtility.RetryAction(() => cmdm.ExecuteNonQuery(), 3, 1000);
                   }
               }
               Console.WriteLine("Finished Locs!");
               cn.Close();
          });
          conn.Close();
    }
}


...

        void RunAllTasks()
        {
            Task[] tasks = { PumpLocsAsync(), PumpPicsAsync() };

            try
            {
                Task.WaitAll(tasks);
                Console.WriteLine("Finished with all tasks...");
                foreach (var task in tasks)
                {
                    Console.WriteLine("Id: {0}, Status: {1}", task.Id, task.Status);
                }
            }

....
4

1 に答える 1

7

の呼び出し方法を誤解しており、メソッドの結果とメソッドへのデリゲートをTask.Factory.FromAsync()渡しています。BeginXxxEndXxx

var rdr = await Task.Factory.FromAsync(
    cmd.BeginExecuteReader,
    (Func<IAsyncResult, SqlDataReader>)cmd.EndExecuteReader,
    null);

操作が完了した後に何かをしたい場合は、この行の下に置くだけawaitで、適切なタイミングで実行されるようになります。

于 2012-04-22T19:51:00.473 に答える