C# EntityFramework(6)和异步(等待激活)?
我已经下载了(为了使用C# EntityFramework(6)和异步(等待激活)?,c#,entity-framework,.net-4.5,async-await,entity-framework-6,C#,Entity Framework,.net 4.5,Async Await,Entity Framework 6,我已经下载了(为了使用async) 所以我写了这个简单的方法: public async Task<List<int>> MyasyncMethod() { var locations = await MyDumpEntities.AgeGroups.Select(f=>f.endYear).ToListAsync(); return locations; } ...Later...
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();
公共异步任务MyasyncMethod()
{
var locations=await MyDumpEntities.AgeGroups.Select(f=>f.endYear.toListSync();
返回地点;
}
后来
DumpEntities1 MyDumpEntities=新的DumpEntities1();
var data=MyDumpEntities.AgeGroups.ToListSync();
MyasyncMethod().ContinueWith(s=>{Response.Write(“f”);});
MyDumpEntities.Dispose();
但我在屏幕上看不到任何东西,当我检查数据时,我看到:
p、 这是ToListAsync
签名
我缺少什么?ToListSync
返回一个任务
。将Page\u Load
标记为async,然后可以在其中使用wait
粗略规则:如果某个东西返回一个任务(方法名中包含“Async”),您必须等待它
另外,在使用async/await时,您不必使用ContinueWith
。只需等待您自己的方法,然后将Write
调用放在下一行
DumpEntities1 MyDumpEntities = new DumpEntities1();
var data = await MyDumpEntities.AgeGroups.ToListAsync();
var dataFromMyMethod = await MyasyncMethod()
Response.Write("f");
MyDumpEntities.Dispose();
并将
Async=“True”
添加到页面指令ToListAsync
返回一个任务
。将Page\u Load
标记为async,然后可以在其中使用wait
粗略规则:如果某个东西返回一个任务(方法名中包含“Async”),您必须等待它
另外,在使用async/await时,您不必使用ContinueWith
。只需等待您自己的方法,然后将Write
调用放在下一行
DumpEntities1 MyDumpEntities = new DumpEntities1();
var data = await MyDumpEntities.AgeGroups.ToListAsync();
var dataFromMyMethod = await MyasyncMethod()
Response.Write("f");
MyDumpEntities.Dispose();
并将
Async=“True”
添加到页面指令中,该指令基于您有问题的注释和行:
var data = MyDumpEntities.AgeGroups.ToListAsync();
数据将是什么类型<代码>任务
。没错,不是列表
。
因此,您必须将页面加载
标记为异步(如果可能):
或者以某种方式等待执行(继续、阻塞等待)
另一件事(如果我错了,其他人可能会想纠正),但是由于您在第二次调用中使用continuation,我会非常小心地处理continuation之外的上下文。结果可能是您先发制人地处理了上下文。在这个特殊的例子中,您没有在继续中使用上下文,但它看起来很可疑
所以我要么
MyasyncMethod().ContinueWith(s => { Response.Write("f"); MyDumpEntities.Dispose();});
或者也可以在那里使用async
var result = await MyasyncMethod();
Response.Write("f");
MyDumpEntities.Dispose();
并将
Async=“True”
添加到页面指令中,该指令基于您有问题的注释和行:
var data = MyDumpEntities.AgeGroups.ToListAsync();
数据将是什么类型<代码>任务
。没错,不是列表
。
因此,您必须将页面加载
标记为异步(如果可能):
或者以某种方式等待执行(继续、阻塞等待)
另一件事(如果我错了,其他人可能会想纠正),但是由于您在第二次调用中使用continuation,我会非常小心地处理continuation之外的上下文。结果可能是您先发制人地处理了上下文。在这个特殊的例子中,您没有在继续中使用上下文,但它看起来很可疑
所以我要么
MyasyncMethod().ContinueWith(s => { Response.Write("f"); MyDumpEntities.Dispose();});
或者也可以在那里使用async
var result = await MyasyncMethod();
Response.Write("f");
MyDumpEntities.Dispose();
并将
Async=“True”
添加到页面指令中其他人指出正确的解决方案是使用wait
,但我看不到很好的解释
原始代码错误的原因有两个。首先,您在ASP.NET应用程序中使用ContinueWith
,而没有捕获上下文,因此continuence(Response.Write
调用)没有请求上下文,因此没有要写入的响应
await
通过在await
之前捕获上下文并使用该上下文恢复方法的其余部分,为您解决此问题;在本例中,它将捕获表示当前请求/响应的AspNetSynchronizationContext
另一个原因是异步代码将并发运行。因此,MyasyncMethod
将开始执行,到达其等待
,并将未完成的任务返回到页面加载
<代码>页面加载然后将一个延续附加到该任务并继续执行,处理上下文。因此,可以在ToListAsync
请求仍在运行时释放上下文
wait
也为您解决了这个问题,因为它将“暂停”Page\u Load
方法,直到myasynchmethod
完成
最后,在ASP .NET:中,当使用<代码>异步代码>代码时,也应该考虑这些要点。
Microsoft.Bcl.Async
targetFramework
设置为4.5,或将UseTaskFriendlySynchronizationContext
设置为truePage.Async
设置为trueRegisterAsyncTask
而不是wait
。我通常更喜欢await
,因为不同的方法有更多的关注点分离,但ASP.NET团队更喜欢RegisterAsyncTask
,因为在PreRender
之后有一个“同步”点,运行时会等待所有操作完成李>
- 使用
取消令牌HttpRequest.TimedOut
- (仅限WebForms/
)您可以通过设置RegisterAsyncTask
并让Page.AsyncTimeout
方法使用async
来添加异步超时CancellationToken
其他人指出正确的解决方案是使用
wait
,但我看不到很好的解释
有两个