【问题标题】:async/await on CacheItemPolicy.UpdateCallback event and other event delegatesCacheItemPolicy.UpdateCallback 事件和其他事件委托的异步/等待
【发布时间】:2015-08-02 05:55:56
【问题描述】:

操作方法:从委托 void 事件方法调用 await 方法?

将(一个 ASP.NET)应用程序转换为异步是完全允许的。但是不支持的地方呢?

var policy = new CacheItemPolicy();
policy.UpdateCallback = CacheEntryUpdateCallback;

void VoidDelegate(CacheEntryUpdateArguments arguments) {
   // need this - but no can't do :(
   await SomeApi.AsyncOnlyMethodAsync(); 
}

那里不允许等待,那该怎么办?这样做的正确方法是什么?这个问题也适用于 WebForms 上的事件处理程序,例如 myButton.Commmand += new CommandEventHandler(VoidDelegate)

答:

void VoidDelegate(CacheEntryUpdateArguments arguments) {
   Task.Factory.StartNew(new Func<Task>(async () => {
     await SomeApi.AsyncOnlyMethodAsync();
   })).Unwrap().Wait();
}

这会起作用,但会启动另一个线程?至少它不会使线程对池有效,并且这里异步的目的已经消失。

或者是否支持 B:

async void VoidDelegate(CacheEntryUpdateArguments arguments) {
  await SomeApi.AsyncOnlyMethodAsync();
}

但这是一劳永逸 - 但缓存更新事件需要在返回结果之前获取新数据。同样适用于例如按钮命令事件 - 页面可以在命令完成之前完成。

【问题讨论】:

  • 试试Task.Run(async () =&gt; away bla);
  • @abatishchev 没有理由这样做。
  • 我会避免调用方法XXXDelegate。它是一个方法,而不是一个委托,所以当它是一个方法时称它为委托是非常混乱的。
  • @abatishchev:这将缺少等待,如果没有 Unwrap,它似乎在大规模上不稳定。信息:blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx
  • @Servy:这里的名字是伪的/只是为了解释它是什么/上下文等

标签: c# asp.net asynchronous async-await task-parallel-library


【解决方案1】:

您可以将任何返回voidTaskTask&lt;T&gt; 的方法标记为async。将方法标记为async 不会更改方法的签名,因此如果您希望将await 标记为async,则可以简单地将其标记为await

请注意,由于您现在有一个async void 方法,这将是一个即发即弃的方法。当有人调用委托时,该方法将很快返回,而异步工作继续进行,调用者将无法知道工作何时完成,或者是否出错。

【讨论】:

  • 您指向的是解决方案 B。但是 - 如果它是即发即弃的,它将不适用于缓存更新(需要在返回结果之前获取新数据)或例如按钮上的命令事件 - 页面将在事件命令完成之前停止执行(或其他不良状态)。
  • @AndersMad 然后,您要么需要同步完成工作,要么更新回调以支持异步(即任务,返回)回调,如果可以的话。
  • 所以你说解决方案 A 是在代码中使用的正确模式,并且在 MS 为(在这个案例)System.Runtime.Caching.MemoryCache?
  • @AndersMad 没有。从来没有这样的正确做法。在这里使用Task.RunTask.StartNew 并没有做任何建设性的事情。如果您真的需要同步完成工作,只需在已有的任务上调用Wait(或Result,视情况而定)即可。将任务包装在另一个任务中只是为了解开它没有任何作用。
  • @AndersMad 如果设置了同步上下文,并且调用的方法将回调发布到该同步上下文,并且在它们返回之前它不会完成并且您同步等待任务然后 i> 你造成了僵局。在这种情况下,您只是在使用一种迂回的方式来删除当前的同步上下文。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 2018-12-27
  • 1970-01-01
  • 2022-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多