首先,这是来自更大的东西,是的,我可以在正常/其他情况下使用await
完全避免这种情况。对于任何有兴趣的人,我将在下面解释。
为了跟踪在我的计划继续之前还剩下多少任务,我已经构建了以下内容:
柜台:
private static int counter;
某种方法:
public static void Test()
{
List<Task> tasks = new List<Task>();
for (int i = 0; i < 10000; i++)
{
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
var task = DoTaskWork();
task.ContinueWith(t => // After DoTaskWork
{
// [...] Use t's Result
counter--; // Decrease counter
tcs.SetResult(null); // Finish the task that the UI or whatever is waiting for
});
tasks.Add(tcs.Task); // Store tasks to wait for
}
Task.WaitAll(tasks.ToArray()); // Wait for all tasks that actually only finish in the ContinueWith
Console.WriteLine(counter);
}
我的超级工作要做:
private static Task DoTaskWork()
{
counter++; // Increase counter
return Task.Delay(500);
}
现在,有趣的是,在查看counter
时,我最终没有收到数字0。相反,数量随每次执行而变化。为什么是这样?我尝试了各种测试,但找不到不规则的原因。 TaskCompletionSource
我认为这是可靠的。感谢。
现在,对于为什么我这样做感兴趣的人:
我需要创建大量任务而不启动它们。为此,我需要使用Task构造函数(一个罕见的用例)。它对Task.Run()
的不利之处在于它无法处理await
的任何内容,并且它需要从任务中返回类型才能正常运行(因此null
作为结果)。因此,我需要解决这个问题。其他想法欢迎......
答案 0 :(得分:2)
好。我很蠢。仅仅5分钟,我意识到了。
我在锁定辅助对象时做了同样的事情,然后以任何方式更改了计数器,现在它可以工作......
{{1}}
答案 1 :(得分:0)
我需要在不启动它们的情况下创建大量任务...因此,我需要解决这个问题。其他想法欢迎......
所以,如果我读得正确,你想要建立一个任务列表,而不是在创建时实际运行它们。您可以通过构建在需要时调用的Func<Task>
对象列表来实现:
async Task Main()
{
// Create list of work to do later
var tasks = new List<Func<Task>>();
// Schedule some work
tasks.Add(() => DoTaskWork(1));
tasks.Add(() => DoTaskWork(2));
// Wait for user input before doing work to demonstrate they are not started right away
Console.ReadLine();
// Execute and wait for the completion of the work to be done
await Task.WhenAll(tasks.Select(t => t.Invoke()));
Console.WriteLine("Ready");
}
public async Task DoTaskWork(int taskNr)
{
await Task.Delay(100);
Console.WriteLine(taskNr);
}
这将起作用,即使你像这样使用Task.Run:
public Task DoTaskWork(int taskNr)
{
return Task.Run(() =>
{
Thread.Sleep(100); Console.WriteLine(taskNr);
});
}
这不是你想要的,你能详细说明你想要创建的任务吗?