考虑这个相当简单的方法:
private bool ValidateKey(HttpRequestMessage message)
{
}
以上方法如下调用
if (!ValidateKey(request))
{
//do something
}
现在我想在ValidateKey中调用一个返回Task的方法。我们假设它是HttpRequestMessage中的ReadAsStringAsync方法:
message.Content.ReadAsStringAsync();
既然这个方法可以异步运行,我理想情况下应该像这样调用它:
string output = await message.Content.ReadAsStringAsync();
但是这需要我改变我的方法签名以包括async和返回类型到Task,然后调用者也包括... ad infinitum。
可以同步调用 ReadAsStringAsync ,即我愿意 ValidateKey 等待 ReadAsStringAsync 完成。这样可以省去更改代码的麻烦,只是为了迎合这一方法。
答案 0 :(得分:8)
没有。如果操作固有异步,则无法同步运行。但是,你可以阻止线程并等待以完成它。
我会高度建议不要这样做。您应该完全执行操作async
,或者根本不使用异步操作。
你也可以使用Stephen Cleary的AsyncContext:
string output = AsyncContext.Run(() => message.Content.ReadAsStringAsync());
如果您仍然计划阻止,那么请使用GetAwaiter().GetResult()
,因为它在await
将执行的异常处理中更接近:
string output = message.Content.ReadAsStringAsync().GetAwaiter().GetResult();
答案 1 :(得分:2)
初始(错误)答案部分(我将留待此处以供将来参考)
您可以使用Task.RunSynchronously
使任务同步运行,但从技术上讲它仍然是异步的,但是您阻止当前执行,因此它是同步的:
Task<string> t = message.Content.ReadAsStringAsync();
t.RunSynchronously();
string result = t.Result;
这仅适用于您的方法返回new Task
(因为您只能调用Run
一次),因此当声明方法async
时,这将不起作用。 .. 的
<强>解决方案强>
只需以同步方式等待结果即可。这将阻止执行。
Task<string> t = message.Content.ReadAsStringAsync();
string result = t.Result;
答案 2 :(得分:1)
ReadAsStringAsync()
返回Task<string>
所以,为了等待(阻止)结果,您只需要获取Result
属性:
var task = message.Content.ReadAsStringAsync();
string output = task.Result;