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());