C# 异步和同步方法
我有一个异步方法:C# 异步和同步方法,c#,async-await,C#,Async Await,我有一个异步方法: public async Task<Foo> GetFooAsync(); 我真的不想完全重写getfooancy的代码,我想做如下事情 public Foo GetFoo() { return GetFooAsync().GetAwaiter().GetResult(); } 这是个好主意还是这个方法有一些不明显的问题?我知道,如果在同步上下文中使用getfooancy().Result,我可能会遇到死锁。但是关于GetFooAsync().Get
public async Task<Foo> GetFooAsync();
我真的不想完全重写getfooancy
的代码,我想做如下事情
public Foo GetFoo()
{
return GetFooAsync().GetAwaiter().GetResult();
}
这是个好主意还是这个方法有一些不明显的问题?我知道,如果在同步上下文中使用
getfooancy().Result
,我可能会遇到死锁。但是关于GetFooAsync().GetAwaiter().GetResult()
?同步/异步代码的混合可能会导致死锁(一路异步的段落)
问题在于
任务
继续运行的位置,这取决于当前的运行状态。如果同步计划在当前被调用Wait()
/Result
/GetResult()
阻止的同一线程上进行,则会遇到问题如果需要同步版本,则单独添加该方法的同步重载,以获得SOC(关注点分离)。I.c.像你已经做的那样,添加一个如下所示的重载
public Foo GetFoo()
{
///code body
}
您不应该在同步运行的方法后面隐藏异步实现,例如使用
Task.Run(async () => await GetFooAsync());
单独实现同步版本,或者让使用者显式同步GetFooAsync。
问题是,运行任务将消耗工作线程,并且可用工作线程池是有限的。您可能会遇到阻塞代码。因此API使用者应该知道同步实现是异步处理的。
返回GetFooAsync().Result代码>?不要使用.Result
使用.GetAwaiter().GetResult()
,因为后者处理聚合异常,前者不处理。如果需要同步版本,请添加shync重载separately@Rahul显然我不明白。你能用一个例子来解释你的想法吗?我同意Rahul的观点,不要用sync调用来包装你的异步方法。咬紧牙关,重写它。一般来说,应该先编写同步版本,然后修改为异步(可能带有标志),还是可以将同步版本简单地包装在工作线程中,以便在异步中生成?@samusarin,否,如回答中所述,最好有两个不同版本的方法,即使在.NET BCL中也可以看到相同的方法。如果您将名称更改为public Foo synchronizedgetfooasync()
?让消费者知道它只是异步方法的包装器。
Task.Run(async () => await GetFooAsync());