[英]The async method lacks await
我在這個主題上發現了很多東西,但是似乎沒有一個示例/答案可以解決我們的問題。 我們不斷收到警告,指出以下方法(以及其他類似方法)缺少等待,但是當我們嘗試添加等待時,我們會收到“無法等待此消息”(無論我們嘗試在哪里添加等待)。 我們做錯了什么?
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;
}
}
非常感謝您的協助!
您已將方法標記為async
但未使用await
。 您的方法沒有理由是async
。 您可以將定義重寫為
protected T PerformGet<T>(string requestUri, bool appendHeader)
async
本質上說:“在這種方法中,我們將await
asnyc調用”
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;
}
}
然后我們擺脫了不必要的try / catch:
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
方法,以接受客戶端應將標頭添加為參數的客戶端。
原因是您沒有像等待的那樣等待任何東西。異步調用結束時會出現結果。 嘗試這個
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;
}
}
您不能同時使用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));
您是否嘗試過:
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;
}
}
基於此:
var webApiResponse = Task.Run(() => _webApiClient.GetAsync(requestUri)).Result;
我建議您退后一步,嘗試了解async
await
為您准備做什么。 有一些學習曲線,但是可以確保您不會因為使用它而使事情變得更糟。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.