5

这有点啰嗦,但这里......

鉴于我有这样的界面:

public interface IWebClientHelper
{
    TPayload Get<TPayload>(string url);
}

的实现对Get提供的 URL 进行调用,该 URL 将返回包含类型为TPayload) 的 Json 对象的响应,并且该 Json 被反序列化TPayload然后返回。

我想让Get方法的实现异步(或者更具体地说,使方法中包含的 HTTP 调用Get异步),但据我了解,这需要将Get方法的签名更改为:

Task<TPayload> Get<TPayload>(string url);

我的目标是保持界面不变,所以我创建了第二个界面:

public interface IAsyncWebClientHelper
{
    Task<TPayload> Get<TPayload>(string url);
}

并将其注入我的IWebClientHelper. 所以现在我的实现IWebClientHelper看起来像这样:

public TPayload Get<TPayload>(string url)
{
    return _asyncWebClientHelper.Get<TPayload>(url).Result;
}

和包含该行的Get方法_asyncWebClientHelper

message = await httpClient.GetAsync(url);

所以我不清楚的是:我认为该行将return _asyncWebClientHelper.Get<TPayload>(url).Result阻止执行直到该方法返回是否正确?或者await该方法中的关键字是否会释放线程,直到它收到来自 url 的响应?

4

1 回答 1

19

是的, usingResult意味着您的方法将阻塞。但是,这很可能意味着它实际上会导致死锁。你没有告诉我们太多关于上下文的信息,但是如果你在一个上下文中,await你需要返回到同一个线程,但是该线程由于 而被阻塞Result,你基本上是在自己身上死锁。在使用任何阻塞调用(例如属性或方法)时,您需要非常小心。ResultWait()

从根本上说,尝试使用异步而不使界面异步是棘手的​​/毫无意义的。你最好全心全意地拥抱异步,或者坚持同步版本。毕竟,如果您要在异步任务完成之前保持线程阻塞,那么首先异步有什么好处?

于 2013-09-03T15:21:28.833 回答