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);
}
}
....
You misunderstood how to call
Task.Factory.FromAsync()
, you pass to it the result of theBeginXxx
method and a delegate to theEndXxx
method: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.