并行执行一组任务,但有一个组超时
Execute set of tasks in parallel but with a group timeout
我目前正在尝试编写一个具有可靠超时值的状态检查工具。我见过如何做到这一点的一种方法是使用 Task.WhenAny() 并包含一个 Task.Delay,但它似乎没有产生我期望的结果:
public void DoIUnderstandTasksTest()
{
var checkTasks = new List<Task>();
// Create a list of dummy tasks that should just delay or "wait"
// for some multiple of the timeout
for (int i = 0; i < 10; i++)
{
checkTasks.Add(Task.Delay(_timeoutMilliseconds/2));
}
// Wrap the group of tasks in a task that will wait till they all finish
var allChecks = Task.WhenAll(checkTasks);
// I think WhenAny is supposed to return the first task that completes
bool didntTimeOut = Task.WhenAny(allChecks, Task.Delay(_timeoutMilliseconds)) == allChecks;
Assert.True(didntTimeOut);
}
我在这里错过了什么?
我认为您混淆了 When...
调用与 Wait...
的工作原理。
Task.WhenAny
不是 return 您传递给它的第一个要完成的任务。相反,它 return 是一个 new 任务,将在 any 内部任务完成时完成。这意味着您的相等性检查将始终 return false - 新任务永远不会等于前一个任务。
您期望的行为似乎类似于 Task.WaitAny
,它将 阻止 当前执行,直到任何内部任务完成,并且 return 已完成任务的索引。
使用 WaitAny,您的代码将如下所示:
// Wrap the group of tasks in a task that will wait till they all finish
var allChecks = Task.WhenAll(checkTasks);
var taskIndexThatCompleted = Task.WaitAny(allChecks, Task.Delay(_timeoutMilliseconds));
Assert.AreEqual(0, taskIndexThatCompleted);
我目前正在尝试编写一个具有可靠超时值的状态检查工具。我见过如何做到这一点的一种方法是使用 Task.WhenAny() 并包含一个 Task.Delay,但它似乎没有产生我期望的结果:
public void DoIUnderstandTasksTest()
{
var checkTasks = new List<Task>();
// Create a list of dummy tasks that should just delay or "wait"
// for some multiple of the timeout
for (int i = 0; i < 10; i++)
{
checkTasks.Add(Task.Delay(_timeoutMilliseconds/2));
}
// Wrap the group of tasks in a task that will wait till they all finish
var allChecks = Task.WhenAll(checkTasks);
// I think WhenAny is supposed to return the first task that completes
bool didntTimeOut = Task.WhenAny(allChecks, Task.Delay(_timeoutMilliseconds)) == allChecks;
Assert.True(didntTimeOut);
}
我在这里错过了什么?
我认为您混淆了 When...
调用与 Wait...
的工作原理。
Task.WhenAny
不是 return 您传递给它的第一个要完成的任务。相反,它 return 是一个 new 任务,将在 any 内部任务完成时完成。这意味着您的相等性检查将始终 return false - 新任务永远不会等于前一个任务。
您期望的行为似乎类似于 Task.WaitAny
,它将 阻止 当前执行,直到任何内部任务完成,并且 return 已完成任务的索引。
使用 WaitAny,您的代码将如下所示:
// Wrap the group of tasks in a task that will wait till they all finish
var allChecks = Task.WhenAll(checkTasks);
var taskIndexThatCompleted = Task.WaitAny(allChecks, Task.Delay(_timeoutMilliseconds));
Assert.AreEqual(0, taskIndexThatCompleted);