代码之家  ›  专栏  ›  技术社区  ›  Silly Dude

C#如何在异步方法中启动一个新的“线程”?

  •  2
  • Silly Dude  · 技术社区  · 3 年前

    我有两个异步方法, 测试1 测试2

    在里面 测试1 ,我想打电话 测试2 “在新线程中”。

    换句话说,我想要一个单独的“线程”来执行 测试2 测试1 跨过 测试2 打电话,不要等它结束。

    private async Task Test2()
    {
        // some time-consuming work to do...
    }
    
    public async Task Test1()
    {
        // How to call Test2 and immediately move on to the next line and let a separate "thread" to
        // execute Test2?
    }
    
    1 回复  |  直到 3 年前
        1
  •  4
  •   Andrii Litvinov    3 年前

    让我们假设 Test2 具有一些CPU密集型逻辑和一些异步调用:

    private async Task Test2()
    {
        for (var i = 1; i < 1_000_000; i++)
        {
        }
    
        await Task.Delay(TimeSpan.FromMinutes(1));
    
        for (var i = 1; i < 1_000_000; i++)
        {
        }
    }
    

    如果 测试2 在没有 await ,则当前线程将在拳头之前执行逻辑 等候 在里面 测试2 返回之前的方法 Test1 。意味着执行将返回 测试1 只在第一次之后 for 循环结束:

    public async Task Test1()
    {
        var _ = Test2();
    }
    

    如果您需要 测试1 测试2 调用,则必须将其调度到来自的另一个线程 ThreadPool ,可以使用 Task.Run ,例如:

    public async Task Test1()
    {
        var _ = Task.Run(() => Test2());
    }
    

    在这种情况下,您无法控制 测试2 实际由执行 线程池 (有可能 测试1 甚至在 测试2 已启动)和任务,由返回 任务.运行 将仅在以下情况下完成 Task2 退出或抛出错误。所以你可以 等候 或者稍后在代码中使用该任务,或者如果您的逻辑不关心结果,则简单地忽略它。

    如果你不打算等待 测试2 方法,值得直接捕获和处理/记录其中可能的错误,否则它将以静默方式失败,这可能会导致难以调查的问题。