阻止我不断在我的.net代码中使用异步/等待模式的原因是,一旦你创建了异步方法,async关键字就会通过我的代码传播,迫使我使所有方法都异步。是否有一种模式可以有效地阻止这种情况?
答案 0 :(得分:3)
阻止我不断在我的.net代码中使用异步/等待模式的原因是,一旦你创建了异步方法,async关键字就会通过我的代码传播,迫使我使所有方法都异步。是否有一种模式可以有效地阻止这种情况?
让我问你这个问题,那么:你为什么要使用async
/ await
?您需要退后一步,决定是否需要异步代码的好处。如果您确实需要这些好处,那么您的代码必须是异步的。 一旦你阻止一个线程,你就失去了异步的所有好处。所以,真的,为什么要使用异步代码,如果你还要阻止一个线程?
也就是说,在某些情况下,部分 - async
堆栈是有意义的。例如,如果您的代码库在转换状态下暂时。在这种情况下,您可以使用我在brownfield async:
所有这些都是黑客攻击,并且都有不同的缺点。在每种情况下都没有适用的黑客。
答案 1 :(得分:0)
如前所述,您应该始终保持异步...
在某些情况下,我们使用litle辅助类来切断异步模式。此类允许您通过替换SynchronizationContext来等待结果而不会导致死锁。
public class NoSynchronizationContextScope : IDisposable
{
private readonly SynchronizationContext synchronizationContext;
public NoSynchronizationContextScope()
{
synchronizationContext = SynchronizationContext.Current;
SynchronizationContext.SetSynchronizationContext(null);
}
public void Dispose() => SynchronizationContext.SetSynchronizationContext(synchronizationContext);
}
void fn()
{
using (new NoSynchronizationContextScope())
{
fnAsync().Wait();
// or
// var result = fnAsync().Result();
// in case you have to wait for a result
}
}
答案 2 :(得分:0)
您可以使用异步方法并在任务中调用非异步方法,因此外部方法的行为类似于异步,内部方法仍然是同步的。
public async Task OuterFuncAsync()
{
await Task.Run(() => InnerFunc());
}
答案 3 :(得分:0)
在您想要开始运行但不等待结果(即触发事件处理程序)的方法的特定情况下,您可以使用async void。只需确保在此时捕获所有错误:
public async void DoSomething() {
try {
var o = await DoThing1();
await DoThing2(o);
} catch (Exception e) {
// Log the error somewhere (to a file, database, etc.)
}
}