我下载了EF6 (为了使用async)
所以我写了一个简单的方法:
public async Task<List<int>> MyasyncMethod()
{
var locations = await MyDumpEntities.AgeGroups.Select(f=>f.endYear).ToListAsync();
return locations;
}
...Later...
DumpEntities1 MyDumpEntities = new DumpEntities1();
var data = MyDumpEntities.AgeGroups.ToListAsync();
MyasyncMethod().ContinueWith(s => { Response.Write("f"); });
MyDumpEntities.Dispose();但是我没有在屏幕上看到任何东西,当我检查data时,我看到了以下内容:

附注:这是ToListAsync签名

我错过了什么?
发布于 2013-07-11 07:25:38
以评论和你有问题的行为基础:
var data = MyDumpEntities.AgeGroups.ToListAsync();data类型是什么?Task<List<AgeGroup>>。没错,不是List<AgeGroup>。因此,您必须将Page_Load标记为异步(如果可能的话):
public async void Page_Load(object sender, EventArgs e)
{
using(var MyDumpEntities = new DumpEntities1())
{
var data = await MyDumpEntities.AgeGroups.ToListAsync();
}
}或者以某种方式等待执行(继续、阻塞等待)。
另一件事(如果我错了,其他人可能想纠正这一点),但是由于您在第二个调用中使用了延续,所以我会非常小心地处理延续之外的上下文。结果可能是您预先处理上下文。在这种情况下,您没有在继续中使用上下文,但它看起来很可疑.
所以我要么
MyasyncMethod().ContinueWith(s => { Response.Write("f"); MyDumpEntities.Dispose();});或者也可以在那里使用async
var result = await MyasyncMethod();
Response.Write("f");
MyDumpEntities.Dispose();并将Async="True"添加到页面指令中。
发布于 2013-07-11 10:39:22
其他人已经指出,正确的解决方案是使用await,但我看不出有什么好的解释。
原始代码错误的原因有两个。首先,您在使用ContinueWith时没有捕获ASP.NET应用程序中的上下文,因此延续( Response.Write调用)没有请求上下文,因此没有要写入的响应。
await通过捕获await之前的上下文并使用该上下文恢复方法的其余部分来为您处理这一问题;在本例中,它将捕获表示当前请求/响应的AspNetSynchronizationContext。
另一个原因是异步代码将并发运行。因此,MyasyncMethod将开始执行,到达其await,并将未完成的任务返回给Page_Load。然后,Page_Load将一个延续附加到该任务,并继续执行,处理上下文。因此,在ToListAsync请求仍在运行时,可能会释放上下文。
await还为您修复了这个问题,因为它将“暂停”Page_Load方法,直到MyasyncMethod完成为止。
最后,在async中使用ASP.NET时,您还应该考虑以下几点:
Microsoft.Bcl.Async。targetFramework设置为4.5,或将UseTaskFriendlySynchronizationContext设置为true。Page.Async设置为true。RegisterAsyncTask而不是await。我通常更喜欢await,因为不同的方法有更多的关注点分离,但是ASP.NET团队更喜欢RegisterAsyncTask,因为在PreRender之后有一个“同步”点,运行时等待所有操作完成。.HttpRequest.TimedOut取消令牌。RegisterAsyncTask)您可以通过设置Page.AsyncTimeout和让async方法接受CancellationToken来添加异步超时。
发布于 2013-07-11 07:23:43
ToListAsync返回一个Task。将Page_Load标记为异步,然后可以在其中使用等待。
粗糙规则:如果某物返回一个任务(方法名中包含“异步”),则必须等待它。
此外,在使用异步/等待时,您不必使用ContinueWith。只需等待您自己的方法,并将Write调用放在下一行。
DumpEntities1 MyDumpEntities = new DumpEntities1();
var data = await MyDumpEntities.AgeGroups.ToListAsync();
var dataFromMyMethod = await MyasyncMethod()
Response.Write("f");
MyDumpEntities.Dispose();并将Async="True"添加到页面指令中。
https://stackoverflow.com/questions/17587157
复制相似问题