我是async / await的新手,我想确保这种做法是正确的:
public async Task DoHeavyWorkAsync()
{
await Task.Run(() => {
getResponseFromFarawaySlowServerAndDoSomethingWithIt();
});
}
public async void ConsumeAsync()
{
Task longRunningTask = DoHeavyWorkAsync();
// do a lot of other stuffs here that does not depend on DoHeavyWorkAsync()
await longRunningTask;
}
这种使用async / await的方式是正确的还是我做错了什么?
答案 0 :(得分:7)
你可以做几件事:
在DoHeavyWorkAsync
中,您真的不需要使用await Task.Run
生成状态机,您只需return Task.Run
:
public Task DoHeavyWorkAsync()
{
return Task.Run(() => getResponseFromFarawaySlowServerAndDoSomethingWithIt());
}
async void
仅适用于异步事件处理程序。如果您的异步方法返回void
,则应返回Task
代替:
public async Task ConsumeAsync()
如果DoHeavyWorkAsync
是基于IO的操作,则无需将其包含在Task.Run
内,因为它本身是异步的。只需使用await
即可。更重要的是,你不应该async over sync。相反,如果需要,您应该使同步方法的调用者明确使用Task.Run
:
public void DoHeavyWork()
{
getResponseFromFarawaySlowServerAndDoSomethingWithIt();
}
然后将其显式包装在调用方法中:
Task.Run(DoHeavyWork);
答案 1 :(得分:2)
从API设计师的角度来看,我会考虑将拆分方法 getResponseFromFarawaySlowServerAndDoSomethingWithIt
改为:
getResponseFromFarawaySlowServer
和doSomething()
。
然后,您只能使用异步包装器
使用:
var response = await getResponseFromFarawaySlowServerAsync();
doSomething(response);
另一件有点气味的事:getResponseFromFarawaySlowServer
本身并不是异步。如果可能的话,应该在该方法中等待http调用或webservice调用本身。目前你正在创建新的线程thad没有什么只是等待。如果您等待http调用
所以改为
string getResponseFromFarawaySlowServer(){
string response = new WebClient().DownloadString(uri);
...
return response
}
async Task<string> getResponseFromFarawaySlowServerAsync(){ Task.StartNew..
你会直接:
async Task<string> getResponseFromFarawaySlowServerAsync(){
string response = await new WebClient().DownloadStringAsync(uri);
...
return response;
}