Task.WaitAny退化案例行为

时间:2016-04-19 19:04:33

标签: task-parallel-library task wait

在以下情况下,我无法找到Task.WaitAny()行为的任何文档:

  1. 给出一系列空任务。
  2. 给出一系列任务,其中一个已经完成。
  3. 鉴于一系列任务,所有任务都已完成。
  4. 我的假设是2& 3将立即返回(#3选择一个任意索引返回,可能是第一个或最后一个取决于实现细节但不保证。)我排序期望1返回true?

1 个答案:

答案 0 :(得分:2)

一些简短的单元测试似乎证实了这一点...以下全部通过。 如果有人能找到这种行为的正式文件,我很高兴看到它。 (即使只是为了提高我下次自己找到它的能力!)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;
using System.Threading;

namespace TANTest.Threading
{
  [TestFixture]
  public class MetaTaskTests
  {
    private const int SafeTimeOutMillisecs = 1000;

    [Test, Timeout(SafeTimeOutMillisecs)]
    public void Meta_NewTaskCompletes()
    {
      var task = new Task(() => { });
      task.Start();
      Thread.Sleep(10);

      Assert.That(task.IsCompleted, Is.True);
    }

    [Test, Timeout(SafeTimeOutMillisecs)]
    public void Meta_EmptySetOfTasks_WaitsProceed()
    {
      var tasks = new List<Task>();
      Task.WaitAny(tasks.ToArray());
      Task.WaitAll(tasks.ToArray());
    }

    [Test, Timeout(SafeTimeOutMillisecs)]
    public void Meta_EmptySetOfTasks_WaitsGiveExpectedOutputs()
    {
      var tasks = new List<Task>();
      Assert.That(Task.WaitAny(tasks.ToArray(), TimeSpan.FromMilliseconds(100)), Is.EqualTo(-1));
      Assert.That(Task.WaitAll(tasks.ToArray(), TimeSpan.FromMilliseconds(100)), Is.True);
    }

    [Test, Timeout(SafeTimeOutMillisecs)]
    public void Meta_SetOfCompletedTasks_WaitsProceed()
    {
      var tasks = new List<Task>
      {
        new Task(() => { }),
        new Task(() => { })
      };

      tasks.ForEach(task => task.Start());
      Thread.Sleep(10);

      Task.WaitAny(tasks.ToArray());
      Task.WaitAll(tasks.ToArray());
    }

    [Test, Timeout(SafeTimeOutMillisecs)]
    public void Meta_SetOfCompletedTasks_WaitsGiveExpectedOutputs()
    {
      var tasks = new List<Task>
      {
        new Task(() => { }),
        new Task(() => { })
      };

      tasks.ForEach(task => task.Start());
      Thread.Sleep(10);

      Assert.That(Task.WaitAny(tasks.ToArray(), TimeSpan.FromMilliseconds(100)), Is.GreaterThan(-1));
      Assert.That(Task.WaitAll(tasks.ToArray(), TimeSpan.FromMilliseconds(100)), Is.True);
    }

    [Test, Timeout(SafeTimeOutMillisecs)]
    public void Meta_SetOfUnstartedTasks_WaitsDontProceed()
    {
      var tasks = new List<Task>
      {
        new Task(() => { }),
        new Task(() => { })
      };

      Thread.Sleep(10);

      Assert.That(Task.WaitAny(tasks.ToArray(), TimeSpan.FromMilliseconds(100)), Is.EqualTo(-1));
      Assert.That(Task.WaitAll(tasks.ToArray(), TimeSpan.FromMilliseconds(100)), Is.False);
    }


    [Test, Timeout(SafeTimeOutMillisecs)]
    public void Meta_SetOfTasksWithOneCompleted_AnyProceedsAndOutputsIndex()
    {
      var tasks = new List<Task>
      {
        new Task(() => { }),
        new Task(() => { })
      };

      tasks.First().Start();
      Thread.Sleep(10);

      Assert.That(Task.WaitAny(tasks.ToArray()), Is.GreaterThan(-1));
    }

    [Test, Timeout(SafeTimeOutMillisecs)]
    public void Meta_SetOfTasksWithOneCompleted_AllTimesOutWithExpectedOutput()
    {
      var tasks = new List<Task>
      {
        new Task(() => { }),
        new Task(() => { })
      };

      tasks.First().Start();
      Thread.Sleep(10);

      Assert.That(Task.WaitAll(tasks.ToArray(), TimeSpan.FromMilliseconds(100)), Is.False);
    }
  }
}