在同一线程中执行await任务之前和之后的代码部分

时间:2018-11-01 07:24:47

标签: c# async-await console

我的控制台应用程序项目中包含以下代码:

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 时,我得到了这个:

enter image description here

当我使用GetValueAsync 不带参数时,我得到了这个:

enter image description here

当我使用await Task.Delay(1000 * delay)时,为什么在同一线程中执行GetValueAsync(int val, int delay, int taskId)之后的代码部分?如果我没有记错,那么等待的那部分应该在新线程中执行...(当前项目是控制台应用程序,主线程不是GUI线程)

2 个答案:

答案 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是不同的任务