简体   繁体   English

如何在c#中计算异步方法的执行时间

[英]how to calculate execution time of a async method in c#

So I have a Async method which does something asynchronously. 所以我有一个Async方法,可以异步执行某些操作。

private async static void DoSomethingAsync (int i){}

I call it in a loop lets say 50 times. 我把它称为循环让我说50次。

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

At the end of loop I want to calculate total processing time, I used Stopwatch but as you can imagine it gives me wrong time as it gets called as soon as after the loop, it does not wait for the DoSomethingAsync to finish processing. 在循环结束时我想计算总处理时间,我使用了秒表但是你可以想象它给了我错误的时间,因为它在循环之后被调用,它不会等待DoSomethingAsync完成处理。

how to tell Stopwatch to wait for all the 50 instances of DoSomethingAsync() to finish. 如何告诉秒表等待DoSomethingAsync()的所有50个实例完成。 I have seen this question, but I cant use Task here. 我已经看到了这个问题,但我不能在这里使用任务。

I don't know why you cannot use Task, my guess is that you are calling it within a Main method or something. 我不知道为什么你不能使用Task,我的猜测是你在Main方法或其他东西中调用它。 So i will go out from that. 所以我会从那里出去。

Like Martin Ullrich said i would change DoSomethingAsync method to return a task: 就像Martin Ullrich说我会改变DoSomethingAsync方法来返回一个任务:

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

Then create a new method that does the loop by adding the methods to a List<Task> : 然后通过将方法添加到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);
}

Now from where you did the loop before, in this case the Main method simply add the new method call in there: 现在你从那里开始循环,在这种情况下, Main方法只是在那里添加新的方法调用:

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

    Console.ReadLine();
}

This is the downside of using async void . 这是使用async void的缺点。 There is no way to do that without modifying the called method (so that it could call a callback, unlock a mutex etc.). 没有修改被调用的方法就没有办法做到这一点(因此它可以调用回调,解锁互斥锁等)。

You can change your method to return async Task instead and create another method that just calls this method without awaiting which can then be used in places you previously needed the async void signature for. 您可以更改您的方法以返回async Task并创建另一个方法,只需调用此方法而无需等待,然后可以在以前需要async void签名的位置使用该方法。

async void why? async void为什么? don't do that, use asnyc Task , or a ActionBlock s or ParallelFor/ForEach . 不要这样做,使用asnyc Task ,或ActionBlockParallelFor/ForEach However purely for novelty (and not to be used as a true gauge), if you want to calculate time in a parallel process id consider putting a timer inside your parallel method and using a global variable and use Interlocked.Add Method Method for thread safety 然而,纯粹为了新颖性(并且不能用作真正的量表),如果要在并行进程中计算时间,请考虑在并行方法中使用计时器并使用全局变量并使用Interlocked.Add方法方法来确保线程安全

private long CombinedMs;

...

private async static void DoSomethingAsync (int i)
{

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

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

}

Anyway, i think you need to go back to the drawing board on tasks... Good luck 无论如何,我认为你需要回到任务的绘图板上......祝你好运

You can have a global counter to keep track of time consumed , something like this. 你可以有一个全局计数器来跟踪消耗的时间,就像这样。

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 
}

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM