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:

中,当使用<代码>异步代码>代码时,也应该考虑这些要点。
  • 您必须以.NET4.5为目标。不要使用
    Microsoft.Bcl.Async
  • 必须将
    targetFramework
    设置为4.5,或将
    UseTaskFriendlySynchronizationContext
    设置为true
  • (仅限WebForms)将
    Page.Async
    设置为true
  • 考虑使用
    RegisterAsyncTask
    而不是
    wait
    。我通常更喜欢
    await
    ,因为不同的方法有更多的关注点分离,但ASP.NET团队更喜欢
    RegisterAsyncTask
    ,因为在
    PreRender
    之后有一个“同步”点,运行时会等待所有操作完成
  • 内置您自己的请求超时。异步ASP.NET请求不会自动使用同步ASP.NET请求内置的正常超时。有两种选择:
    • 使用
      HttpRequest.TimedOut
      取消令牌
    • (仅限WebForms/
      RegisterAsyncTask
      )您可以通过设置
      Page.AsyncTimeout
      并让
      async
      方法使用
      CancellationToken
      来添加异步超时

  • 其他人指出正确的解决方案是使用
    wait
    ,但我看不到很好的解释

    有两个