我想在我的程序,實現如下調用堆棧/工作流程:死鎖
- 訊()
- 授權()
- httpPost()
我的想法是,httpPost()
將是異步的,而另外兩種方法仍然是非異步的。但是,由於某種原因,除非我做了2 + 3,否則它不適用於我。異步。也許我仍然有一些誤解。
據我的理解,我可以a)在調用異步方法時使用await
關鍵字(這將掛起方法並在異步方法完成後繼續)或者b)省略關鍵字,而是調用Task。異步方法的結果返回值,該值將阻塞直到結果可用。
讓我告訴你的工作示例:
private int dispatch(string options)
{
int res = authorize(options).Result;
return res;
}
static async private Task<int> authorize(string options)
{
string values= getValuesFromOptions(options);
KeyValuePair<int, string> response = await httpPost(url, values);
return 0;
}
public static async Task<KeyValuePair<int, string>> httpPost(string url, List<KeyValuePair<string, string>> parameters)
{
var httpClient = new HttpClient(new HttpClientHandler());
HttpResponseMessage response = await httpClient.PostAsync(url, new FormUrlEncodedContent(parameters));
int code = (int)response.StatusCode;
response.EnsureSuccessStatusCode();
string responseString = await response.Content.ReadAsStringAsync();
return new KeyValuePair<int, string>(code, responseString);
}
讓我告訴你的非木材加工例如:
private int dispatch(string options)
{
int res = authorize(options).Result;
return res;
}
static private int authorize(string options)
{
string values= getValuesFromOptions(options);
Task<KeyValuePair<int, string>> response = httpPost(url, values);
doSomethingWith(response.Result); // execution will hang here forever
return 0;
}
public static async Task<KeyValuePair<int, string>> httpPost(string url, List<KeyValuePair<string, string>> parameters)
{
var httpClient = new HttpClient(new HttpClientHandler());
HttpResponseMessage response = await httpClient.PostAsync(url, new FormUrlEncodedContent(parameters));
int code = (int)response.StatusCode;
response.EnsureSuccessStatusCode();
string responseString = await response.Content.ReadAsStringAsync();
return new KeyValuePair<int, string>(code, responseString);
}
我也試圖讓所有3種方法非異步,並替換httpPost
中的await
與.Result
S,但隨後它會永遠在該行掛HttpResponseMessage response = httpClient.PostAsync(url, new FormUrlEncodedContent(parameters)).Result;
可能有人開導我,並說明我的錯誤是什麼?
若要測試這是否正確的解釋,採取非工作代碼並將每個「await X」更改爲「await X.ConfigureAwait(false)」。如果解釋是正確的,它現在應該工作。 另一個注意事項:如果你在ASP.Net或UI應用程序中運行,你有一個SynchronizationContext。如果是這樣,請比較在獨立控制檯項目中運行相同的代碼。 – danarmak
@servy:然而,我沒有得到的是我的工作示例和非工作示例之間的實際區別。我明白你說'await'安排了一個延續,'.Result'只是普通塊(是這樣嗎?),但這不會意味着我需要一個無盡的異步等待鏈,因爲沒有'await'我會阻止/死鎖我的線程? 我的意思是第一個例子在'int res = authorize(options).Result;'中不*攔截,但第二個例子在'doSomethingWith(response.Result)中攔截;爲什麼? – user826955