异步和同步方法
我有一个异步方法:异步和同步方法
public async Task<Foo> GetFooAsync();
我需要它的同步版本。事情是这样的:
public Foo GetFoo();
我真的不希望完全重写的GetFooAsync
代码,我希望做一些诸如
public Foo GetFoo()
{
return GetFooAsync().GetAwaiter().GetResult();
}
这是好主意还是这个方法有任何不明显的问题?据我所知,如果我在同步上下文中使用GetFooAsync().Result
,我可能会遇到死锁问题。但是GetFooAsync().GetAwaiter().GetResult()
呢?
混合同步/异步代码可能导致死锁as described in this article(段落“异步一路”)。
问题是Task
继续运行,这取决于当前SynchronizationContext
。如果同步意味着如果你想有一个同步的版本,然后按顺序分别添加方法的shynchronous过载,因此目前已被调用Wait()
/Result
/GetResult()
你正在运行陷入困境
你应该不躲在一个同步运行的方法,例如异步执行通过使用
Task.Run(async() => await GetFooAsync());
要么单独实现同步版本,要么让消费者显式同步GetFooAsync。 问题是,运行该任务将消耗工作线程,并且可用的工作者池是有限的。您可能会遇到阻止代码。所以API消费者应该意识到同步实现是异步处理的。
如果将名称更改为'public Foo SynchronisedGetFooAsync()',该怎么办?所以消费者知道它只是一个异步方法的包装。 –
''return GetFooAsync()。Result;''? –
请勿使用'.Result'使用'.GetAwaiter()。GetResult()',因为后者处理聚合异常,前者不会。 – Lloyd
如果你想要一个同步版本,然后分别添加一个shync过载 – Rahul