【发布时间】:2014-05-06 17:01:05
【问题描述】:
我在 asp.net 中有一个 HTTPHandler,我想使用 4.5 异步等待代码将其转换为异步。然而,并非我们所有的代码都是 4.5,因此我们应用程序的内部部分(库、基础设施)目前需要保持在 4.0。我遇到了一个问题,我想为我们的一些共享库提供一个 lambda。 lambda 是异步的,但我需要库代码来等待它完成,但没有死锁。到目前为止,我还没有弄明白。
假设处理程序如下所示:
// .NET 4.5 website
public class MyHandler : HttpTaskAsyncHandler
{
public override async Task ProcessRequestAsync(HttpContext context)
{
var someLibrary = new SharedLibrary();
someLibrary.PostProcess = async (x,y) => {
await ProcessXY(x,y);
}
await someLibrary.ProcessAsync();
// write out some content here
}
private async Task ProcessXY(int x, int y) {
// make some external calls
var someLib = new SomeOtherLibrary();
await someLib.CallAsync(x,y);
}
}
然后 SharedLibrary 看起来像这样:
// .NET 4.0 class library
public class SharedLibrary {
public Action<int,int> PostProcess { get; set; }
public Task ProcessAsync() {
return Task.Factory.StartNew(() => Process(), CancellationToken.None,TaskCreationOptions.None,TaskScheduler.FromCurrentSynchronizationContext());
}
public void Process() {
// do some processing
if (PostProcess != null) {
// call PostProcess synchronously
PostProcess(1,2);
}
// do some final processing
}
}
就目前的代码而言,对 PostProcess 的调用在 lambda 完全运行完成之前返回。如果我将 PostProcess 切换到 Func<int,int,Task> 并调用为 PostProcess(1,2).Wait() 那么我会死锁。有没有办法在这样的混合 4.5/4.0 代码中完成?
【问题讨论】:
-
你可以在.NET 4.0中使用
await,只要你还在使用C# 5.0,即使你不能使用await,你仍然可以在.NET中编写异步程序4.0,这只是要做更多的工作,并且做得很好。您的 4.0 代码不需要是同步的。 -
尝试给 Process 方法一个返回类型,我认为会强制运行时等待它实际返回。 msdn.microsoft.com/en-us/library/…
-
需要
ProcessXY在// do some final processing之前完成,还是只需要在// write out some content here之前完成? -
是 ProcessXY 需要在最终处理之前完成。 Process 获取分布式锁(这不是 CLR 锁),PostProcess 对数据进行一些额外的修改。最后的处理是保存然后释放锁。
标签: c# asp.net .net-4.0 async-await .net-4.5