C# CacheItemPolicy.UpdateCallback事件和其他事件委托上的异步/等待
如何:从委托void事件方法调用wait方法 将(ASP.NET)应用程序转换为异步应用程序是一项非常重要的任务。但那些不受支持的地方呢C# CacheItemPolicy.UpdateCallback事件和其他事件委托上的异步/等待,c#,asp.net,asynchronous,async-await,task-parallel-library,C#,Asp.net,Asynchronous,Async Await,Task Parallel Library,如何:从委托void事件方法调用wait方法 将(ASP.NET)应用程序转换为异步应用程序是一项非常重要的任务。但那些不受支持的地方呢 var policy = new CacheItemPolicy(); policy.UpdateCallback = CacheEntryUpdateCallback; void VoidDelegate(CacheEntryUpdateArguments arguments) { // need this - but no can't do :(
var policy = new CacheItemPolicy();
policy.UpdateCallback = CacheEntryUpdateCallback;
void VoidDelegate(CacheEntryUpdateArguments arguments) {
// need this - but no can't do :(
await SomeApi.AsyncOnlyMethodAsync();
}
等待是不允许的,那怎么办呢?正确的做法是什么?这个问题也适用于WebForms上的事件处理程序,如myButton.Commmand+=newcommandEventHandler(VoidDelegate)
是A:
void VoidDelegate(CacheEntryUpdateArguments arguments) {
Task.Factory.StartNew(new Func<Task>(async () => {
await SomeApi.AsyncOnlyMethodAsync();
})).Unwrap().Wait();
}
async void VoidDelegate(CacheEntryUpdateArguments arguments) {
await SomeApi.AsyncOnlyMethodAsync();
}
但这是一个fire-and-forget-但是缓存更新事件需要在返回结果之前获取新数据。例如按钮命令事件-页面可以在命令完成之前完成。您可以将任何返回
无效
、任务
或任务
的方法标记为异步
。将一个方法标记为async
不会更改该方法的签名,因此,如果希望等待
事情,您可以简单地将VoidDelegate
标记为async
请注意,由于您现在有一个
异步void
方法,因此这将是一个fire-and-forget方法。当有人调用委托时,方法将很快返回,而异步工作将继续进行,调用方将无法知道工作何时完成,或者是否出错。TryTask.Run(async()=>awe bla)
@abatishchev没有理由这么做。我会避免调用方法XXXDelegate
。这是一个方法,而不是委托,所以当它是一个方法时,将其称为委托是非常令人困惑的。@abatishchev:这将错过等待,并且如果没有展开,它似乎在大规模上是不稳定的。信息:@Servy:这里的名称是伪的/仅用于解释它是什么/context等。您指向的是解决方案a B。但是-如果它是一个火,并且忘记了它对缓存更新(需要在返回结果之前获取新数据)或按钮上的命令事件都不起作用-页面将停止执行(或其他错误状态)在事件命令完成之前。@AndersMad则您需要同步完成工作,或者更新回调以支持异步(即任务、返回)回调(如果可以)。因此,您说解决方案A是代码中使用的正确模式,而真正的异步在这里是不可能的(释放回IIS/web服务器的线程),直到MS为(在本例中)生成异步事件System.Runtime.Caching.MemoryCache?@AndersMad No.从来没有一个时间是正确的操作过程。您使用任务没有做任何有建设性的事情。运行或任务。在此处开始新建。如果您确实需要同步完成工作,只需调用等待(或结果,视情况而定)在您已经拥有的任务上。将任务包装到另一个任务中只是为了打开它,不会产生任何效果。@AndersMad如果设置了同步上下文,并且调用的方法将回调发送到该同步上下文,则在它们返回并且您同步等待该任务之前,该任务不会完成,那么您就造成了死锁。在这种情况下,您将e只是使用一种迂回的方式来删除当前的同步上下文。