【问题标题】:When async-await change thread?什么时候异步等待更改线程?
【发布时间】:2017-04-19 14:17:48
【问题描述】:
  • 当我调用 test1() 方法时,ManagedThreadId 将在之后更改 延迟(1)。
  • 当我调用 test2() 方法(而不是 test1())然后调用 ManagedThreadId 将保持不变。

async-await什么时候换线程?

在 test2() 方法中,完成方法所需的时间甚至比在 test1() 中更长

    [Route("api/[controller]")]
    [HttpGet]
    public async Task<IActionResult> Get()
    {
        await MainAsync();
        return new ObjectResult(null);
    }

    static async Task MainAsync()
    {
        Console.WriteLine("Main Async: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
        await test1();
        //await test2();
        // . . .more code
    }

    private static async Task test1()
    {
        Console.WriteLine("thisIsAsyncStart: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
        await Task.Delay(1);
        Console.WriteLine("thisIsAsyncEnd: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
    }

    private static async Task test2()
    {
        Console.WriteLine("thisIsAsyncStart: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
        System.Threading.Thread.Sleep(5000);
        await Task.FromResult(0);
        Console.WriteLine("thisIsAsyncEnd: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
    }

【问题讨论】:

  • 我建议你阅读How different is await/async from threading?的答案...
  • 我有一个async intro 可以帮助你。
  • 假设您将一只鸡放入烤箱中烤,然后在等待时支付一些账单。 什么时候把鸡放进烤箱让你雇了一个秘书来付账单?它没有。异步与多个工作线程无关。这是关于将任务分解成更小的部分,以便您可以及时重新排序。

标签: c# async-await


【解决方案1】:

test1 等待 Task.Delay(1)不会在等待它的时候完成,这意味着需要将 test1 的其余部分安排为延续。

对于test2,您正在等待Task.FromResult,这将始终返回已完成的Task。当您await 一个已经完成的任务时,该方法可以继续在当前线程上运行,而无需安排继续。

【讨论】:

  • 好的。但是为什么在我调用 await test1() 的那一刻没有创建新线程; (或等待 test2())?这个方法没有被遵守,它正在等待一段时间。但是当我调用 await "Task.Delay(1);"方法比线程改变。
  • @Raskolnikov test1 实际上调用了一个尚未完成的异步操作,所以它本身最终会在完成之前返回,这意味着,当等待时,调用者也会返回,然后在当前同步上下文中执行该方法的其余部分。 test2 永远不会等待任何未完成的 Task 实例,因此它将最终同步运行,而不是返回不完整的 Task,这意味着当您 await it 它只是运行同步并解包Task
  • 我还在为此苦苦挣扎。 await test1(); 之间有什么不同?并等待 Task.Delay(1);。两者都是方法,都是静态的并且都返回任务。为什么要考虑等待 await Task.Delay(1);但不考虑等待 await test1(); ?方法 test1() 是与方法 Task.Delay(1) 相同的长时间运行过程?
  • @Raskolnikov 正如我在回答开头所说的那样,重要的是返回的Task 是否已经完成。如果它已经完成,它将同步继续。
  • 换句话说,虽然async/await 本身不会产生新线程,但等待不完整的Task 将导致在任务完成时为调用者​​更改执行线程ID。在我的例子中,我在 async 方法中创建了一个 WPF 表单对象,但是在运行 await Task.Delay(500) 之后,我突然在一个不拥有该对象的新线程上导致了 InvalidOperationException
猜你喜欢
  • 2019-01-28
  • 1970-01-01
  • 2012-11-05
  • 1970-01-01
  • 2020-07-08
  • 2013-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多