Как рассчитать время выполнения асинхронного метода в C # - PullRequest
0 голосов
/ 24 мая 2018

Итак, у меня есть метод Async, который делает что-то асинхронно.

private async static void DoSomethingAsync (int i){}

Я вызываю это в цикле, скажем, 50 раз.

for (int i = 0; i < 50; i++)
 {
    DoSomethingAsync (i);
 }

В конце цикла я хочучтобы вычислить общее время обработки, я использовал секундомер, но, как вы можете себе представить, он дает мне неправильное время, так как он вызывается сразу после цикла, он не ожидает завершения обработки DoSomethingAsync.

как заставить секундомер ждать завершения всех 50 экземпляров DoSomethingAsync ().Я видел этот вопрос, но я не могу использовать Задачу здесь.

Ответы [ 4 ]

0 голосов
/ 24 мая 2018

У вас может быть глобальный счетчик для отслеживания потребляемого времени, что-то вроде этого.

public class YourClass
{

TimeSpan tSpan;


public void PerformOp()
{
tSpan=new TimeSpan();
for (int i = 0; i < 50; i++)
 {
    DoSomethingAsync (i);
 }

}

private async static void DoSomethingAsync (int i)
{
Stopwatch stp = new StopWatch();
stp.Start();
//your Operation here
stp.Stop();
tSpan+=stp.Elapsed;//not the exact systax or usage but you get the idea 
}

}
0 голосов
/ 24 мая 2018

async void почему?не делайте этого, используйте asnyc Task или ActionBlock s или ParallelFor/ForEach.Однако исключительно для новизны (и не для использования в качестве истинного измерителя), если вы хотите рассчитать время в идентификаторе параллельного процесса, рассмотрите возможность помещения таймера в ваш параллельный метод и использования глобальной переменной и используйте Interlocked.Add Method Метод обеспечения безопасности потоков

private long CombinedMs;

...

private async static void DoSomethingAsync (int i)
{

   var sw = new StopWatch();
   sw.Start();
   ...
   sw.Stop();

   Interlocked.Add(ref CombinedMs,sw.ElapsedMillisecond);

}

В любом случае, я думаю, вам нужно вернуться к чертежной доске для выполнения заданий ... Удачи

0 голосов
/ 24 мая 2018

Я не знаю, почему вы не можете использовать Task, я предполагаю, что вы вызываете его в методе Main или как-то еще.Итак, я выйду из этого.

Как сказал Мартин Уллрих, я бы изменил метод DoSomethingAsync для возврата задачи:

private async static Task DoSomethingAsync(int i)
{
    ...
}

Затем создайте новый метод, который выполняет цикл, добавивметоды для List<Task>:

private static async void PerformLoop()
{
    Stopwatch timer = new Stopwatch();
    timer.Start();
    List<Task> l = new List<Task>();
    for (int i = 0; i < 50; i++)
    {
        l.Add(DoSomethingAsync(i));
    }
    await Task.WhenAll(l);
    timer.Stop();

    Console.WriteLine(timer.Elapsed.TotalSeconds);
}

Теперь, откуда вы делали цикл раньше, в этом случае метод Main просто добавляет туда новый вызов метода:

static void Main(string[] args)
{
    PerformLoop();

    Console.ReadLine();
}
0 голосов
/ 24 мая 2018

Это недостаток использования async void.Невозможно сделать это без изменения вызываемого метода (чтобы он мог вызвать обратный вызов, разблокировать мьютекс и т.просто вызывает этот метод без ожидания, который затем можно использовать в местах, для которых ранее требовалась подпись async void.

...