我正在开发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