C#中如何计算异步方法的执行时间
how to calculate execution time of a async method in c#
所以我有一个 Async 方法可以异步执行某些操作。
private async static void DoSomethingAsync (int i){}
我循环调用了 50 次。
for (int i = 0; i < 50; i++)
{
DoSomethingAsync (i);
}
在循环结束时,我想计算总处理时间,我使用了 Stopwatch,但你可以想象它给了我错误的时间,因为它在循环后立即被调用,它不等待 DoSomethingAsync完成处理。
如何告诉秒表等待 DoSomethingAsync() 的所有 50 个实例完成。我看到了 this 个问题,但我不能在这里使用任务。
这是使用 async void
的缺点。如果不修改被调用的方法(以便它可以调用回调、解锁互斥量等),就无法做到这一点。
您可以将您的方法更改为 return async Task
并创建另一个只调用此方法而不等待的方法,然后可以在您以前需要 async void
签名的地方使用对于.
async void
为什么?不要那样做,使用 asnyc Task
,或 ActionBlock
s 或 ParallelFor/ForEach
。然而纯粹是为了新奇(而不是用作真正的衡量标准),如果你想在并行进程中计算时间 id 考虑在你的并行方法中放置一个计时器并使用全局变量并使用 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);
}
无论如何,我认为你需要重新开始任务...祝你好运
我不知道您为什么不能使用 Task,我猜您是在 Main 方法或其他方法中调用它。所以我会从那里出去。
正如 Martin Ullrich 所说,我会将 DoSomethingAsync
方法更改为 return 任务:
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();
}
你可以有一个全局计数器来跟踪消耗的时间,就像这样。
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
}
}
所以我有一个 Async 方法可以异步执行某些操作。
private async static void DoSomethingAsync (int i){}
我循环调用了 50 次。
for (int i = 0; i < 50; i++)
{
DoSomethingAsync (i);
}
在循环结束时,我想计算总处理时间,我使用了 Stopwatch,但你可以想象它给了我错误的时间,因为它在循环后立即被调用,它不等待 DoSomethingAsync完成处理。
如何告诉秒表等待 DoSomethingAsync() 的所有 50 个实例完成。我看到了 this 个问题,但我不能在这里使用任务。
这是使用 async void
的缺点。如果不修改被调用的方法(以便它可以调用回调、解锁互斥量等),就无法做到这一点。
您可以将您的方法更改为 return async Task
并创建另一个只调用此方法而不等待的方法,然后可以在您以前需要 async void
签名的地方使用对于.
async void
为什么?不要那样做,使用 asnyc Task
,或 ActionBlock
s 或 ParallelFor/ForEach
。然而纯粹是为了新奇(而不是用作真正的衡量标准),如果你想在并行进程中计算时间 id 考虑在你的并行方法中放置一个计时器并使用全局变量并使用 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);
}
无论如何,我认为你需要重新开始任务...祝你好运
我不知道您为什么不能使用 Task,我猜您是在 Main 方法或其他方法中调用它。所以我会从那里出去。
正如 Martin Ullrich 所说,我会将 DoSomethingAsync
方法更改为 return 任务:
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();
}
你可以有一个全局计数器来跟踪消耗的时间,就像这样。
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
}
}