【问题标题】:Difference in using Task.Delay or Task.Run to start a task使用 Task.Delay 或 Task.Run 启动任务的区别
【发布时间】:2019-12-18 18:34:43
【问题描述】:

以下两个结果都导致 for 循环在它自己的线程上运行。在 for 循环完成之前,它们都不会被标记为完成。

class Program
{
    static async Task SomethingAsync()
    {
        await Task.Run(() =>
            {
                for (int i = 0; i < 100; i++)
                    Console.WriteLine("s11{0}  {1}", i, Thread.CurrentThread.ManagedThreadId);
            }
        );
    }
    static async Task SomethingAsync2()
    {
        await Task.Delay(1);
        for (int i = 0; i < 100; i++)
            Console.WriteLine("s22{0}  {1}", i, Thread.CurrentThread.ManagedThreadId);
    }
    static void Main(string[] args)
    {
        var t1 = SomethingAsync();
        var t2 = SomethingAsync2();

        for (int i = 0; i < 300; i++)
            Console.WriteLine("m{0}  {1}  {2}  {3}", i, Thread.CurrentThread.ManagedThreadId,t1.IsCompleted,t2.IsCompleted);
    }
}

有什么功能上的区别吗? (除了明显的延迟)

在 SomethingAsync2() 的情况下,Task.Delay 是我错误地发现的。 await 可以调用任何返回 GetAwaiter 的方法吗?

【问题讨论】:

  • 您是只对控制台应用程序感兴趣,还是对 Windows 窗体也感兴趣?
  • 在本例中它是一个控制台应用程序和一个学习实验。我曾预计Something2() 方法最终会回到MainThread。我想看看它是如何阻止它的,但令人惊讶的是它最终出现在一个备用的 WorkerPool 线程上。但是,如果我能在 Forms 中得到不同的结果,那就很好理解了。
  • 是的,如果进程有一个 Windows 消息队列(即它是一个 GUI 应用程序),那么 await Task.Delay() 之后的继续将被编组到正在处理消息队列的 UI 线程上(假设 @ 987654323@ 是从 UI 线程调用的)。如果进程没有消息队列(例如控制台应用程序)或未从 UI 线程调用 Task.Delay(),则线程池中的线程将用于继续。
  • await Task.Run 几乎总是一个错误。 Task.Run - “请找一些其他线程来运行这段代码,我还有其他工作要做”。 await - “好吧,在其他工作完成之前,我没有什么有用的工作要做”
  • @Damien_The_Unbeliever 如果你想在后台调用一个长时间运行的方法并在它返回时更新 UI 怎么办?在这种情况下使用awaitTask.Run() 可以避免在后台任务完成后调用Control.Invoke() 来更新UI。

标签: c# async-await task


【解决方案1】:

由于控制台应用程序没有同步上下文,因此将始终将延续安排到线程池线程。

但是,如果存在同步上下文(如在 Windows 窗体、WPF、UWP 等中),则将向捕获的同步上下文发布延续。

请参阅ConfigureAwait FAQ

顺便说一句,Task.Yield() 可以在不涉及计时器的情况下使用 Task.Delay(1) 执行您尝试执行的操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多