Основы асинхронной обработки потоков цикла

#c# #asynchronous

#c# #асинхронный

Вопрос:

Я надеюсь, что это довольно простой пример кода, который я пытаюсь понять.

Я хотел бы продолжать запускать процесс заново, ожидая завершения длительного процесса. Цель состоит в том, чтобы запускать все пакеты одновременно. Например:

 while(moreToProcess())
{
   var batch = CreateBatch();
   await ssisMethod(batch); //takes 30 seconds and would like to start next batch
   CreateAndSendReports(batch); //Must wait for ssisMethod to complete
}
  

Я обеспокоен тем, что я не понимаю поток моего кода.

  1. Запустится ли другой пакет во время ожидания?
  2. Будет ли это ждать завершения перед созданием отчетов?

как и было запрошено:

Важная часть, я думаю:

       public static async Task ssisMehtod(varBatch)
      {                      
            using (OleDbConnection conn = new OleDbConnection(cstr))
            {
                using (OleDbCommand cmd = new OleDbCommand(sql, conn))
                {
                    cmd.Parameters.Add("@p1", OleDbType.Integer).Value = batchID;
                    cmd.Parameters.Add("@p2", OleDbType.VarWChar, 9).Value = DUNS;
                    conn.Open();
                    await cmd.ExecuteNonQueryAsync();
                }
            }
       }
  

Комментарии:

1. —> он будет ждать завершения перед созданием отчетов. Однако это также будет зависеть от того, что вы написали на ssisMethod Например, запустите и забудьте какую-то задачу .. Можете ли вы опубликовать код этого метода тоже.

2. Спасибо. Я пытаюсь преобразовать синхронизацию в асинхронную

3. Вы можете прочитать эту статью learn.microsoft.com/en-us/dotnet/csharp/programming-guide/… который даст разъяснение по поводу async / await.

4. @пользователь1672994. Я прочитаю эту статью, но я также опубликовал соответствующую часть рассматриваемого метода

Ответ №1:

Вы можете сохранить все задачи и запустить их вместе после продолжения кода WhenAll

        var tasks = new List<Task>();

        while (condition is true)
        {
            tasks.Add(Task.Run(async () =>
            {
                var batch = CreateBatch();
                await ssisMethod(batch); 
                CreateAndSendReports(batch); 
            }));
        }

        Task.WhenAll(tasks);
  

Ответ №2:

Чтобы ответить на ваш вопрос:

  1. Нет, он не запустит другой пакет во время ожидания. Что это делает, так это просто освобождает основной поток, поэтому ваш основной поток / поток пользовательского интерфейса не будет там зависать.
  2. Да, он будет ждать, пока ssisMethod не вернется, прежде чем CreateAndSendReports

Чтобы достичь своей цели, вы можете просто преобразовать свой метод CreateAndSendReports в async. И создайте другой метод-оболочку, например ProcessBatch .

 public static async Task ProcessBatch(Batch batch)
{
  await ssisMethod(batch).ConfigureAwait(false);
  await CreateAndSendReports(batch).ConfigureAwait(false);
}

while(moreToProcess())
{
   var batch = CreateBatch();
   ProcessBatch(batch).ConfigureAwait(false); //Program will not wait here, it will proceed to create another batch.
}