我的控制台应用程序项目中包含以下代码:
static void Main()
{
Console.WriteLine($@"{Thread.CurrentThread.ManagedThreadId}, main");
var list = new List<Task<int>>();
for (int i = 1; i < 4; i++)
{
list.Add(GetValueAsync(i, i, i));
//list.Add(GetValueAsync());
}
var whenAll = Task.WhenAll(list);
whenAll.Wait();
Console.WriteLine(@"End program");
Console.ReadLine();
}
private static async Task<int> GetValueAsync(int val, int delay, int taskId)
{
Console.WriteLine($@"{Thread.CurrentThread.ManagedThreadId}, task{taskId} sleep");
await Task.Delay(1000 * delay);
Console.WriteLine($@"{Thread.CurrentThread.ManagedThreadId}, task{taskId} awake");
return val;
}
private static int index = 0;
private static async Task<int> GetValueAsync()
{
index++;
Console.WriteLine($@"{Thread.CurrentThread.ManagedThreadId}, task{index} sleep");
await Task.Delay(2000);
Console.WriteLine($@"{Thread.CurrentThread.ManagedThreadId}, task{index} awake");
return 10;
}
当我使用带有参数的GetValueAsync 时,我得到了这个:
当我使用GetValueAsync 不带参数时,我得到了这个:
当我使用await Task.Delay(1000 * delay)
时,为什么在同一线程中执行GetValueAsync(int val, int delay, int taskId)
之后的代码部分?如果我没有记错,那么等待的那部分应该在新线程中执行...(当前项目是控制台应用程序,主线程不是GUI线程)
答案 0 :(得分:3)
这些问题总是很难回答,因为对于刚接触该主题的人来说,答案似乎永远无法令人满意
如果将代码更改为以下代码。您将获得预期的结果
list.Add(GetValueAsync(i, 1, i));
输出
1, main
1, task1 sleep
1, task2 sleep
1, task3 sleep
5, task2 awake
4, task3 awake
6, task1 awake
End program
那么最初的结果怎么了?简单地说,需要更多线程,回调发生足够的延迟才能重用同一线程。 任务计划程序认为无需为您分配更多(或不同的)资源
答案 1 :(得分:1)
您的2个功能没有相同的延迟
第一个具有可变的延迟(1、2和3秒),第二个具有恒定的延迟(2秒)
如果您写
await Task.Delay(2000); //instead of await Task.Delay(1000 * delay);
您将获得与第二个功能相同的结果
threadid并不是一个增量值,当线程结束时,其“ id”可用
在您的情况下,相同的threadID是不同的任务