Reputation: 1053
So I have a Async method which does something asynchronously.
private async static void DoSomethingAsync (int i){}
I call it in a loop lets say 50 times.
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.
how to tell Stopwatch to wait for all the 50 instances of DoSomethingAsync() to finish. I have seen this question, but I cant use Task here.
Upvotes: 11
Views: 20932
Reputation: 457
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
}
}
Upvotes: 0
Reputation: 850
I don't know why you cannot use Task, my guess is that you are calling it within a Main method or something. So i will go out from that.
Like Martin Ullrich said i would change DoSomethingAsync
method to return a task:
private async static Task DoSomethingAsync(int i)
{
...
}
Then create a new method that does the loop by adding the methods to a 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:
static void Main(string[] args)
{
PerformLoop();
Console.ReadLine();
}
Upvotes: 15
Reputation: 81573
async void
why? don't do that, use asnyc Task
, or a ActionBlock
s or ParallelFor/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
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
Upvotes: 4
Reputation: 100751
This is the downside of using 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.
Upvotes: 5