I have an async
intro you may find helpful.
Asynchronous code does not always run faster. In fact, a straight line-by-line translation to asynchronous code usually runs slower. The key benefit of asynchronous code is concurrency: it frees up the calling thread to do other work while the asynchronous operation is in progress.
To review your code:
Task.WhenAll(waitOne);
This doesn't actually do anything. WhenAll
will return a Task
that completes when waitOne
completes, but then the task returned from WhenAll
is ignored.
List1.Add(callWcf(y).Result);
Here your code stars an asynchronous operation (callWcf
) and then turns around and immediately and synchronously blocks waiting for it to complete (Result
).
await Task.Yield();
This code is pointless. Apparently it's only there to silence the compiler warnings about async
methods not containing an await
.
here = client.GetThisInt(i);
And here the code is synchronously blocking again.
As I describe in my async best practices article, one of the principles of async
is to use "async all the way". It's easiest to do this from the lowest level (look for anything I/O-based) and work your way up. In this case, the best place to start is the WCF call:
static async Task<string> CallWcfAsync(int i)
{
using (ServiceReference1.Client client = new AsyncTests.ServiceReference1.Client())
{
return await client.GetThisIntAsync(i);
}
}
I also changed the method name to match the TAP conventions.
Next, you move to the caller(s) of that method:
static async Task Load(int i)
{
for (int y = 0; y < i; y++)
{
List1.Add(await CallWcfAsync(y));
}
}
or if you want to execute multiple calls simultaneously:
static async Task LoadAsync(int i)
{
var tasks = Enumerable.Range(0, i).Select(y => CallWcfAsync(y));
List1.AddRange(await Task.WhenAll(tasks));
}
Finally, your Main
method does have to block on a task; this is one of the very rare situations where calling Result
or Wait
is permissible:
LoadAsync(1000).Wait();