我有一个简单的async和await示例,我正在努力完成,并且执行没有像我预期的那样返回给调用者。下面是顶层方法:
protected async void MyDDL_SelectedIndexChanged(object sender, EventArgs e)
{
Task longRunningTask = LongRunningOperationAsync();
DoOtherStuff1();
DoOtherStuff2();
DoOtherStuff3();
await longRunningTask;
}下面是LongRunningOperationAsync方法,它不像预期的那样工作,并且同步运行:
private async Task LongRunningOperationAsync()
{
var myValues = await GetStuffViaLongRunningTask();
//Code to work with myValues here...
}以下是GetStuffViaLongRunningTask的定义
private async Task<IList<MyClass>> GetStuffViaLongRunningTask()
{
//...Calls to get and build up IList<MyClass>
return results;
}问题是上面的代码做了,而不是,返回给调用者,并开始像我预期的那样运行DoOtherStuff1();方法。但是,与调用我自己的方法并将其替换为对await Task.Delay(10000);的调用(如所有简单示例所示)不同,代码的工作方式与预期的一样:
private async Task LongRunningOperationAsync()
{
//Returns to caller as expected:
await Task.Delay(10000);
}使用上述代码的调用方具有longRunningTask,其状态为WaitingForActivation,而不是RanToCompletion,这表明它仍在处理中。
您可能会说我的GetStuffViaLongRunningTask()方法运行得如此之快,而我只是看不到结果。然而,它总是在3-7秒之间运行,当调试时,您可以知道调用是阻塞的和同步的。
我在这里做错了什么,这样我对LongRunningOperationAsync()的调用就不会在到达await单词以调用该方法中的LongRunningOperationAsync时异步工作。
发布于 2013-10-07 19:20:56
假设//...Calls to get and build up IList<MyClass>是同步的CPU绑定工作,那么问题是,在GetStuffViaLongRunningTask结束或到达其第一个await调用之前,它不会返回。您应该得到关于该方法的编译器警告,因为它是一个没有await的await方法。
相反,方法不应该是async,而是向调用方清楚地表明它是同步工作的。只需将签名调整为:
private IList<MyClass> GetStuffViaLongRunningTask()然后,在调用它时,使用Task.Run确保长时间运行的CPU绑定工作在另一个线程中完成:
private async Task LongRunningOperationAsync()
{
var myValues = await Task.Run(() => GetStuffViaLongRunningTask());
//Code to work with myValues here...
}发布于 2013-10-07 19:22:20
//...Calls to get and build up IList<MyClass>
你得告诉我们正在打哪些电话。如果您想在这个结构中使用异步/等待,那么您需要进行异步调用。
如果您的GetStuffViaLongRunningTask函数没有执行异步调用,那么您可以启动一个新任务,如下所示:
private Task<IList<MyClass>> GetStuffViaLongRunningTask()
{
return Task.Factory.StartNew(() =>
{
//...Calls to get and build up IList<MyClass>
// You can make synchronous calls here
return list;
});
}https://stackoverflow.com/questions/19232575
复制相似问题