Async SQL query execution - Task.WaitAll(tasks) ne

2019-05-26 11:13发布

I have an app to move data from a MS SQL server into a MySQL server using async query execution; the data moves fine but Task.WaitAll(tasks) call in the RunAllTasks() method never completes.

The async tasks all follow the pattern of PumpLocsAsync() where the call to MS SQL is invoked asynchronously via BeginExecuteReader; when the reader returns with results, then MySQL inserts normally.

..

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);
                }
            }

....

1条回答
神经病院院长
2楼-- · 2019-05-26 11:58

You misunderstood how to call Task.Factory.FromAsync(), you pass to it the result of the BeginXxx method and a delegate to the EndXxx method:

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

If you want to do something after the operation completes, simply put it below this line, await will make sure it executes at the right time.

查看更多
登录 后发表回答