C# Task.WaitAll-不等待?

C# Task.WaitAll-不等待?,c#,multithreading,parallel-processing,task-parallel-library,C#,Multithreading,Parallel Processing,Task Parallel Library,我正试图了解Task并行库中的Task.WaitAll(..) 我正在运行一个测试,使用以下代码尝试模拟两个任务,一个任务的运行时间比指定的等待时间长(10秒),另一个任务的运行时间比指定的等待时间短(3秒)。指定的时间为5秒。我使用的代码如下: Task<int>[] tasks = new Task<int>[] { Task.Factory.StartNew<int>(()=> { Thread.Sl

我正试图了解Task并行库中的Task.WaitAll(..)

我正在运行一个测试,使用以下代码尝试模拟两个任务,一个任务的运行时间比指定的等待时间长(10秒),另一个任务的运行时间比指定的等待时间短(3秒)。指定的时间为5秒。我使用的代码如下:

Task<int>[] tasks = new Task<int>[]
{
    Task.Factory.StartNew<int>(()=>
        {
            Thread.Sleep(10000);
            return 1;
        }),
    Task.Factory.StartNew<int>(()=>
        {
            Thread.Sleep(3000);
            return 2;
        })
};

TimeSpan timeSpan = new TimeSpan(0, 0, 5);
Task.WaitAll(tasks,timeSpan);

int[] results = new int[tasks.Length];
for(int i = 0; i < tasks.Length;i++)
{
    Console.WriteLine(tasks[i].Result);
}
我希望只得到以下输出,因为另一个线程执行的时间比预期的等待时间长

1

我是否误解了这一点,或者做了错误的测试?

不要使用线程。在任务中睡眠。
任务调度程序不保证每个任务有一个线程,睡眠可能会影响其他任务(请参阅)。请改为使用。

尝试将时间跨度转换为

TimeSpan span = new TimeSpan(0, 0, 0, 10, 0);
//TimeSpan(Days, hours, minutes, seconds, milliseconds);

虽然Task.Delay通常是您想要使用的(因此您不会在睡眠期间浪费线程),但您的问题实际上与此无关

这里发生的情况是,当您打印结果时,您正在访问每个任务的Result属性。这会阻止任务完成,因此您在WaitAll中等待5秒,然后在打印10秒任务的结果时再等待5秒

根据您声明的意图,您需要在访问结果之前检查任务状态,因为您的意图不是阻止它,而是仅在任务碰巧已经完成时才打印出来:

int[] results = new int[tasks.Length];
for (int i = 0; i < tasks.Length; i++)
{
    if (tasks[i].IsCompleted)
    {
        Console.WriteLine(tasks[i].Result);
    }
}

这只在4.5版本中可用吗?@CitadelCSAlum不幸的是,Task.Delay()仅在.Net 4.5中可用。切换到任务。延迟实际上无法解决此问题,因为原因是在10秒任务完成之前访问Result属性被阻塞。这不应该是问题所在。是小时、分钟、秒。更不用说,如果我要更改其创建方式,将使用TimeSpan.From第(10)秒:哦,你接受了错误的答案记住,有时候UI需要时间来绘制。
int[] results = new int[tasks.Length];
for (int i = 0; i < tasks.Length; i++)
{
    if (tasks[i].IsCompleted)
    {
        Console.WriteLine(tasks[i].Result);
    }
}
Task<int>[] tasks = new Task<int>[]
{
    Task.Factory.StartNew<int>(()=>
        {
            Thread.Sleep(10000);
            return 1;
        }),
    Task.Factory.StartNew<int>(()=>
        {
            Thread.Sleep(3000);
            return 2;
        })
};

TimeSpan timeSpan = new TimeSpan(0, 0, 5);
var stopwatch = Stopwatch.StartNew();
Task.WaitAll(tasks, timeSpan);
Console.WriteLine("WaitAll took {0} seconds", stopwatch.Elapsed.TotalSeconds);

int[] results = new int[tasks.Length];
for (int i = 0; i < tasks.Length; i++)
{
    stopwatch = Stopwatch.StartNew();
    Console.WriteLine(tasks[i].Result);
    Console.WriteLine("Printing result took {0} seconds", stopwatch.Elapsed.TotalSeconds);
}
WaitAll took 4.9996961 seconds
1
Printing result took 5.0050012 seconds
2
Printing result took 0.0004338 seconds