我想问一下这个任务是否完成了.延迟调用任务.运行在下面,这是线程id更改的原因,还是背后有不同的逻辑?

async Task Main()
{
     Console.WriteLine(Thread.CurrentThread.ManagedThreadId); //11
     await Task.Delay(200);
     Console.WriteLine(Thread.CurrentThread.ManagedThreadId); //22
}

推荐答案

Task.Delay号不叫Task.Run号.它只返回一个在指定的持续时间后完成的Task,并调用ThreadPool上附加到它的任何continuations.它在内部使用System.Threading.Timer.其实现如下所示:

public class Task
{
    public static Task Delay(int millisecondsDelay)
    {
        var tcs = new TaskCompletionSource();
        _ = new Timer(_ => tcs.SetResult(), null, millisecondsDelay, -1);
        return tcs.Task;
    }
}

因此,当您在Task.Delay中输入await时,await之后的继续在调用Timer回调的同一个线程上运行,这恰好是一个ThreadPool线程.

Note:以上述实现为例.这不是实际的实现,也不能保证正确工作.Timer实例没有存储在任何地方,因此在调用回调之前,它可能会被垃圾收集,导致永远无法完成Task.

Csharp相关问答推荐

HttpContext. RequestAborted当Android APP失go 连接时未取消

通过条件列表删除/更新EF Core 7中的实体的有效方法

JSON空引用异常仅在调试器中忽略try-Catch块,但在其他上下文中捕获得很好

共享暂存/生产环境中Azure事件中心的建议配置

我如何让我的秒表保持运行场景而不重置

为什么C#认为这个非托管 struct 有一个重叠

是否有必要在ASP.NET Core中注册可传递依赖项?

该函数不能检测两条曲线的交点

单元测试类型为HttpClient with Microsoft.Extensions.Http.Resilience

使用ASP.NET MVC for Lemon Squeezy X-Signature创建散列

.NET8Blazor-为什么Rapzor渲染在for循环之后显示?

KeyDown从我的文本框中删除输入,如何停止?

多个参数的最小API删除

在C#/ASP.NET Core 7中,什么可能导致POST请求作为GET请求发送

ASP.NET Core 8 Web API:如何添加版本控制?

在.Net 8 Visual Studio 2022中启用本机AOT发布时发布失败

使用ITfoxtec.Identity.Saml2解析相同键多值SAML 2声明

Unity 3D-意外轴捕捉和未知力对脉冲react 行为的影响

Avalonia MVVM数据模板

使用c#中的Windows 10关机消息