我在这个主题上找到了很多,但没有一个例子/答案似乎解决了我们的问题。我们不断收到警告,说下面的方法(以及其他类似的方法)都没有等待,但是当我们尝试添加等待时,我们得到了#34;无法等待这个" (无论我们在哪里尝试添加等待)。我们做错了什么?
protected async Task<T> PerformGet<T>(string requestUri, bool appendHeader)
{
try
{
_webApiClient = new HttpClient { BaseAddress = _baseAddress };
if (appendHeader) AppendDefaultHeaders();
var webApiResponse = Task.Run(() => _webApiClient.GetAsync(requestUri)).Result;
var responseContent = webApiResponse.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<T>(responseContent);
}
catch (Exception ex) {
throw ex;
}
}
非常感谢任何帮助!
答案 0 :(得分:4)
您已标记方法async
,但未使用await
。您的方法没有理由async
。您可以将定义重写为
protected T PerformGet<T>(string requestUri, bool appendHeader)
async
基本上说'在这种方法中,我们将await
asnyc call'
答案 1 :(得分:4)
async
是一个关键字,它将方法标记为编译器完全重写以支持async / await模式的候选方法。
在内部使用await
关键字的每个位置都会分割该方法。如果您将某个方法标记为async
但不使用await
,则会因为您将其标记为不必要,或者您忘记使用await
而抱怨。这就是你得到编译器错误的原因。
现在,下一步是将await
添加到您的方法中,但这意味着稍微更改它:
.Result
容易出现死锁,这就是await
派上用场的地方所以让我们改写你的方法。首先,我们摆脱对Task.Result
的调用,并替换为await
:
protected async Task<T> PerformGet<T>(string requestUri, bool appendHeader)
{
try
{
_webApiClient = new HttpClient { BaseAddress = _baseAddress };
if (appendHeader) AppendDefaultHeaders();
var webApiResponse = await Task.Run(() => _webApiClient.GetAsync(requestUri));
var responseContent = await webApiResponse.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(responseContent);
}
catch (Exception ex) {
throw ex;
}
}
然后我们摆脱了不必要的任务任务:
protected async Task<T> PerformGet<T>(string requestUri, bool appendHeader)
{
try
{
_webApiClient = new HttpClient { BaseAddress = _baseAddress };
if (appendHeader) AppendDefaultHeaders();
var webApiResponse = await _webApiClient.GetAsync(requestUri);
var responseContent = await webApiResponse.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(responseContent);
}
catch (Exception ex) {
throw ex;
}
}
然后我们摆脱了不必要的尝试/捕获:
protected async Task<T> PerformGet<T>(string requestUri, bool appendHeader)
{
_webApiClient = new HttpClient { BaseAddress = _baseAddress };
if (appendHeader) AppendDefaultHeaders();
var webApiResponse = await _webApiClient.GetAsync(requestUri);
var responseContent = await webApiResponse.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(responseContent);
}
然后我们将HttpClient
对象放入using
语句中:
protected async Task<T> PerformGet<T>(string requestUri, bool appendHeader)
{
using (var client = new HttpClient { BaseAddress = _baseAddress })
{
if (appendHeader) AppendDefaultHeaders(client);
var response = await client.GetAsync(requestUri);
var responseContent = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(responseContent);
}
}
这会删除字段,这在执行异步工作时通常是一个坏主意,并使其成为此方法的本地概念。这还需要更改AppendDefaultHeaders
方法以接受客户端应将标头添加为参数。
答案 2 :(得分:2)
原因是你没有等待任何事情。在异步调用结束时结果。试试这个
protected async Task<T> PerformGet<T>(string requestUri, bool appendHeader)
{
try
{
_webApiClient = new HttpClient { BaseAddress = _baseAddress };
if (appendHeader) AppendDefaultHeaders();
var webApiResponse = await Task.Run(() => _webApiClient.GetAsync(requestUri));
var responseContent = await webApiResponse.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(responseContent);
}
catch (Exception ex) {
throw ex;
}
}
答案 3 :(得分:1)
您无法同时使用await
和.Result
。这是一个或另一个。 Result
将阻止你的线程,直到异步方法完成,就像它是一个同步方法。 await
表示在方法运行时线程将被移回线程池,并且当方法完成时,它将获取另一个线程以继续该函数的其余部分。所以你的功能应该是:
protected async Task<T> PerformGet<T>(string requestUri, bool appendHeader)
{
try
{
_webApiClient = new HttpClient { BaseAddress = _baseAddress };
if (appendHeader) AppendDefaultHeaders();
var webApiResponse = await Task.Run(() => _webApiClient.GetAsync(requestUri));
var responseContent = await webApiResponse.Content.ReadAsStringAsync().;
return JsonConvert.DeserializeObject<T>(responseContent);
}
catch (Exception ex) {
throw ex;
}
}
此外,Task.Run(...)
有点无意义,只需使用var webApiResponse = await _webApiClient.GetAsync(requestUri));
答案 4 :(得分:0)
你试过这个:
protected async Task<T> PerformGet<T>(string requestUri, bool appendHeader)
{
try
{
_webApiClient = new HttpClient { BaseAddress = _baseAddress };
if (appendHeader) AppendDefaultHeaders();
var webApiResponse = await Task.Run(() => _webApiClient.GetAsync(requestUri));
var responseContent = await webApiResponse.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(responseContent);
}
catch (Exception ex) {
throw ex;
}
}
答案 5 :(得分:0)
基于此:
wxSplitterWindow
我建议您退后一步,尝试了解var webApiResponse = Task.Run(() => _webApiClient.GetAsync(requestUri)).Result;
async
正在尝试为您做些什么。有一点学习曲线,但它会确保你不会因为使用它而使事情变得更糟。