所以我有一个Async方法,可以异步执行某些操作。
private async static void DoSomethingAsync (int i){}
我在一个循环中称它为50次。
for (int i = 0; i < 50; i++)
{
DoSomethingAsync (i);
}
在循环结束时我想计算总处理时间,我使用了秒表,但是你可以想象它给了我错误的时间,因为它在循环之后被调用,它不会等待DoSomethingAsync完成处理。
如何告诉秒表等待DoSomethingAsync()的所有50个实例完成。我见过this问题,但我不能在这里使用任务。
答案 0 :(得分:5)
我不知道为什么你不能使用Task,我的猜测是你在Main方法或其他东西中调用它。所以我会从那里出去。
就像Martin Ullrich所说,我会改变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();
}
答案 1 :(得分:4)
这是使用async void
的缺点。没有修改被调用的方法就没有办法做到这一点(这样它就可以调用回调,解锁互斥锁等)。
您可以更改方法以返回async Task
,然后创建另一种方法,只需调用此方法而无需等待,然后可以在之前需要async void
签名的位置使用该方法。
答案 2 :(得分:3)
async void
为什么?不要这样做,请使用asnyc Task
或ActionBlock
或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);
}
无论如何,我认为你需要回到任务的绘图板上......祝你好运
答案 3 :(得分:0)
你可以有一个全局计数器来跟踪消耗的时间,就像这样。
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
}
}