我正在開發VS2013,.NET FW 4.5.1中的WinForms應用程序。這是我與有關結構內部註釋減少代碼:異步等待WhenAll不等待
// Progress object implementing IProgress<MyProgressData>
var progressCallback = new Progress<MyProgressData>();
// listOfMyList is actually List<List<MyObject>>, which contains list of
// list of MyObject's which will be executed as tasks at once.
// For example, this would be sample structure for list of lists:
// List1
// MyObject1
// MyObject2
// MyObject3
// List2
// MyObject4
// MyObject5
// MyObject6
// List1's and List2's objects would be executed as all tasks at once, but List1 and List2 respectively
// would be executed one after another (because of resources usage inside TASK CODE)
foreach (var myItem in listOfMyList)
{
var myList = myItem.ToList();
// Create a list of tasks to be executed (20 by default; each taking from 30-60 seconds)
// Here cs is actually MyObject
var myTasks = myList.Select(cs => Task.Run(async() =>
{
// TASK CODE (using cs as an input object and using "cancellationToken.ThrowIfCancellationRequested();" inside execution to cancel executing if requested)
}, cancellationToken));
await Task.WhenAll(myTasks); // Wait for all tasks to finish
// Report progress to main form (this actually calls an event on my form)
await Task.Run(() => progressCallback.Report(new MyProgressData() { props }), CancellationToken.None);
}
正如你所看到的,我建造進度的對象,然後我列出的清單。頂層列表中的每個項目都應以序列化方式執行(一個接一個地執行)。每個項目的列表元素應該以任務的形式立即執行。 到目前爲止,所有的任務都開始了,甚至什麼時候都會等待它們。或者至少我是這麼想的。我已經把相關的方法記錄下來,向我展示代碼執行。事實證明,雖然進程邏輯(在底部)正在執行,但foreach循環開始執行另一批任務,但它不應該這樣做。 我在這裏錯過了什麼嗎?是否阻止進程代碼或等待Report方法完成執行。也許我錯過了異步/等待。等待,我們確保代碼不會繼續,直到方法完成後?它不會阻塞當前線程,但它也不會繼續執行? 它甚至有可能(因爲它的發生,它可能是),我的foreach循環繼續執行,而進度報告仍然在旅途中?
此代碼駐留在異步方法中。它實際上是所謂的像這樣(讓我們假設這種方法是async MyProblematicMethod()
):
while (true)
{
var result = await MyProblematicMethod();
if (result.HasToExitWhile)
break;
}
從MyProblematicMethod利用一切方法了等待,等待異步方法,而不是多次調用。
無法在此處重現您的問題。在任務完成之前,執行不會傳遞任何「await」操作符。我猜你的錯誤在更高的地方。也許你的方法被多次調用? –
編輯問題以顯示其調用方式。這是異步的,無處不在。有可能,我在其他地方發現了bug,幾乎在一週內找不到它。 – Jure
這應該工作。發佈任務代碼。也許lambda體返回。 – usr