假设:
表中没有“一直异步”选项,因为它会破坏向后兼容性。
public class Impl {
// This works fine when used asynchronously
public Task<Guid> SaveThingAsync(Thing thingToSave) {
return await _storageProvider.saveAsync(thingToSave);
}
public Guid SaveThing(Thing thingToSave) {
// "Obviously", this code creates a deadlock when called
// from within the request context
// return SaveThingAsync(thingToSave).Result
// Not so obviously, this also creates a deadlock
// return SaveThingAsync(thingToSave)
// .ConfigureAwait(false)
// .GetAwaiter()
// .GetResult()
// This was deadlocking, but magically stopped
// return Task.Run(
// async () => await SaveThingAsync(thingToSave)
// .ConfigureAwait(false)
// ).Result;
// This one works
var saveTask = Task.Run(async () =>
await SaveThingAsync(thingToSave)));
var result = saveTask.ConfigureAwait(false).GetAwaiter().GetResult();
return result;
}
为什么?
答案 0 :(得分:1)
Task.Run
步骤&#34;外部&#34;请求上下文 - 它只在线程池上下文中运行。因此,它不会死锁,因为SaveThingAsync
不会在请求上下文中恢复。
在旁注中,ConfigureAwait(false)
在那里毫无意义,因为没有await
可供配置。
另一方面,&#34;一直异步&#34;应该还是一个选择。 WebAPI和WCF客户端不关心他们调用的实现是同步还是异步。将与异步实现的WCF方法同步实现的WCF方法更改为客户端代码不可见。