C# Task.WaitAll-不等待?
我正试图了解Task并行库中的Task.WaitAll(..) 我正在运行一个测试,使用以下代码尝试模拟两个任务,一个任务的运行时间比指定的等待时间长(10秒),另一个任务的运行时间比指定的等待时间短(3秒)。指定的时间为5秒。我使用的代码如下: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<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