Reputation: 211
I have a method void getInformation()
that calls 5 other methods of which each is getting some data from a database. It takes about 1 second until all data is collected and returned to getInformation()
and because of that I thought I should collect the data in the background. My question is: can I just make getInformation()
async
so the UI isn't blocked while the other methods are collecting the information or do I have to make every of the other methods async
?
private void button_Click(object sender, EventArgs e)
{
await getContactInformation();
}
public async Task getContactInformation()
{
this.data.Add(collectData1());
this.data.Add(collectData2());
this.data.Add(collectData3());
this.data.Add(collectData4());
this.data.Add(collectData5());
}
Upvotes: 0
Views: 172
Reputation: 3451
No. Your method body has to use an await or you'll get a warning.
Easy enough.
Wrap your method body with...
await Task.Run(()=>{
// do your thing
});
Upvotes: 2
Reputation: 456322
First off, the ideal situation for async
is to use "async all the way". In this case, your code would look like this:
private async void button_Click(object sender, EventArgs e)
{
await getContactInformationAsync();
}
public async Task getContactInformationAsync()
{
this.data.Add(await collectData1Async());
this.data.Add(await collectData2Async());
this.data.Add(await collectData3Async());
this.data.Add(await collectData4Async());
this.data.Add(await collectData5Async());
}
Note that modern database APIs such as Entity Framework 6, ADO.NET, SQLite, etc, all have asynchronous APIs that you can use to implement the collectDataNAsync
methods. This is the ideal async
scenario, since it minimizes thread waste and also keeps the UI nicely responsive.
However, if you want more of a "quick fix", then you can push the (synchronous) calls off to a background thread, and then treat that background work asynchronously, as such:
private async void button_Click(object sender, EventArgs e)
{
await Task.Run(() => getContactInformation());
}
public void getContactInformation()
{
this.data.Add(collectData1());
this.data.Add(collectData2());
this.data.Add(collectData3());
this.data.Add(collectData4());
this.data.Add(collectData5());
}
This would solve your immediate problem (freeing up the UI thread) at the expense of a thread pool thread. It's not ideal but it would work.
Upvotes: 2
Reputation: 149518
can I just make getInformation() async so the UI isn't blocked while the other methods are collecting the information or do I have to make every of the other methods async ?
The latter. When you go async
it is "async all the way", meaning you make async
method calls all the way to the top of your stack. For IO bound operations, there isn't a need to use background threads, since most APIs these days expose XXXAsync
method calls which are truely asynchronous, which means your UI message loop is free to process other messages while the IO request executes.
An important thing to note though is that marking a method async
is not enough to make it asynchronous. You actually have to await
an async operation, such as your database method call. If there's no async API call to your database, you wont be able to go async.
In you case, getContactInformation
will make the compiler omit a warning saying you have an async method which isn't being awaited. De-Facto, if you await getInformation()
, you will be running completely synchronously.
Upvotes: 1
Reputation: 6202
In general I would recommend all IO to be taken off the UI thread, but there is no point in making each individual call async
.
For guidance on the effect of async
calls on database IO blocked threads, I found this very clear and useful advice.
http://blogs.msdn.com/b/rickandy/archive/2009/11/14/should-my-database-calls-be-asynchronous.aspx
Upvotes: 2