我有一个async方法:
public async Task<string> GenerateCodeAsync()
{
string code = await GenerateCodeService.GenerateCodeAsync();
return code;
}
我需要从一个同步方法调用这个方法。
我如何才能做到这一点,而不必复制GenerateCodeAsync方法,以使其同步工作?
更新
但没有找到合理的解决方案。
但是,我看到HttpClient已经实现了这个模式
using (HttpClient client = new HttpClient())
{
// async
HttpResponseMessage responseAsync = await client.GetAsync(url);
// sync
HttpResponseMessage responseSync = client.GetAsync(url).Result;
}
你可以访问任务的Result属性,这将导致你的线程阻塞,直到结果可用:
string code = GenerateCodeAsync().Result;
注意:在某些情况下,这可能会导致死锁:对Result的调用阻塞主线程,从而阻止异步代码的其余部分执行。你有以下选项来确保这种情况不会发生:
添加.ConfigureAwait(false)到你的库方法或
显式地在线程池线程中执行async方法,并等待它完成:
string code = Task.Run(() => GenerateCodeAsync).Result;
这并不意味着你应该在所有异步调用之后盲目地添加.ConfigureAwait(false) !有关为什么以及何时应该使用.ConfigureAwait(false)的详细分析,请参阅以下博客文章:
.NET博客:ConfigureAwait FAQ
您可以使用同步方法生成器库(nuget)来生成此代码的同步版本。
使用方法如下:
[Zomp.SyncMethodGenerator.CreateSyncVersion]
public async Task<string> GenerateCodeAsync()
{
string code = await GenerateCodeService.GenerateCodeAsync();
return code;
}
它会生成GenerateCode方法,你可以同步调用。
将要生成的源是:
public string GenerateCode()
{
string code = GenerateCodeService.GenerateCode();
return code;
}