我可以创建一个返回Task <t>同步运行的方法吗?</t>

时间:2015-03-18 08:20:28

标签: c# async-await

考虑这个相当简单的方法:

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 完成。这样可以省去更改代码的麻烦,只是为了迎合这一方法。

3 个答案:

答案 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;