我有一個通用應用程序,可更新來自Internet源的多個對象。爲了更新進度指示器並防止重複請求,我有以下邏輯。異步/等待鏈掛起或死鎖
在刷新按鈕:
foreach (var package in Packages.Where(item => !item.Received))
{
RefeshPackage(package);
}
其中在列表中呼籲RefreshPackage每個包:
private async Task RefeshPackage(PackageModel package)
{
if (Tasks.Contains(package.Id)) return;
Tasks.Add(package.Id);
await DownloadAndUpdate(package);
Tasks.Remove(package.Id);
Refresh.RaiseCanExecuteChanged();
}
這對於每個包調用下載升級:
private async Task DownloadAndUpdate(PackageModel package)
{
var response = await webService.GetPackageStages(package.Id);
if (response != null)
{
switch (response.Status)
{
case 200:
package.UpdateStages(response.Stages);
break;
case 500:
//package doesn't exist or website down
break;
default:
break;
}
}
else
{
//no network/timed out
}
}
這對於要求GetPackageStages每個包裝:
public async Task<ResponseData> GetPackageStages(string id)
{
var requestUri = string.Concat(MyUri, id);
var client = new HttpClient();
client.Timeout = new TimeSpan(0,0,5);
try
{
var response = await client.GetAsync(requestUri);
if(response.StatusCode == System.Net.HttpStatusCode.OK)
{
//process response
}
catch (Exception e)
{
return null;
}
finally
{
client.Dispose();
}
}
懸/鎖死總是發生在最後一個函數,在該行:
await client.GetAsync(requestUri);
有時它掛在這裏永遠有時它工作得很好。我已經閱讀了很多關於死鎖的其他解答,常見的解決方案是,使用異步/等待(我已經在做)或使用。配置等待(false)無處不在(我已經做了沒有成功)。
是否還有別的我失蹤或應該以不同的方式構建我的代碼?我已經用完了想法/解決方案。任何幫助,將不勝感激。
'RefreshPackage'是一種異步方法。你爲什麼不對外部'foreach'循環中產生的'Task'做任何事情?即使你不想等待它,至少你應該觀察它的錯誤('.ContinueWith(,... TaskContinuationOptions.OnlyOnFaulted)')。 – 2015-03-02 12:21:52
你會怎麼知道?你不等待'RefeshPackage(package)'的結果;' – Jodrell 2015-03-02 12:22:19
它是掛起還是去//沒有網絡/超時情況? – gabba 2015-03-02 12:24:13