Sleep() 方法后的代码片段没有被执行

Posted

技术标签:

【中文标题】Sleep() 方法后的代码片段没有被执行【英文标题】:Code snippets after Sleep() method does not get executed 【发布时间】:2021-09-01 19:51:03 【问题描述】:

我正在尝试理解 C# 中的任务和并行性。我在控制台应用程序中有以下代码。我期待 Sleep() 方法之后的代码在 3 毫秒后运行,但程序退出了。

任何人都可以提供见解,说明为什么它没有等待 3 毫秒并完成剩余代码的执行。如何让剩余代码在 3 毫秒后执行?

    static void Main(string[] args)
    

        Task task = new Task(() =>
        
            Console.WriteLine("Task on thread 0 started.",
            Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(3000);
            Console.WriteLine("Task on thread 0 finished.",
            Thread.CurrentThread.ManagedThreadId);
        );

        task.Start();
        Console.WriteLine("this is the main thread");

       

    

【问题讨论】:

问:我期待 Sleep() 方法之后的代码在 3 毫秒后运行,但程序退出了。 A:程序退出是因为你没有做任何事情来阻止它退出。就个人而言,我建议在您的最终“Console.WriteLine()”之后放置一个Console.ReadLine()。还有其他选择。例如,您可以在 Main() 中调用 task.Wait():docs.microsoft.com/en-us/dotnet/api/… Sleep 的参数以毫秒为单位。 Sleep(3000) 将休眠 3 秒,而不是 3 毫秒。您正在将后台工作分派到线程池线程(这是一个“后台线程”,不会让您的应用程序保持活动状态)。程序的工作方式是启动应用程序,将工作分派到线程池线程。它开始,然后停止 3 秒。同时,前台线程继续运行并退出,在 Sleep 结束之前结束您的应用程序的执行。 附带说明,专家不赞成使用Task 构造函数创建任务,除非您正在执行需要它的高级操作。启动delegate-based 任务的常用方法是使用Task.Run 方法。 感谢 @paulsm4 提供对代码的见解。我知道为什么代码没有按预期工作。 @Flydog57 感谢您提供见解。这很有帮助。 【参考方案1】:

使用await Task.Delay(3000); 代替Thread.Sleep(3000);(示例如下)。

请注意,下面的 sn-p 是原始代码 sn-p 的修改版本,但对演示进行了修改。

static async Task Main()

    await Task.Run(async () =>
    
        Console.WriteLine("Task on thread 0 started.", Thread.CurrentThread.ManagedThreadId);
        await Task.Delay(3000);
        Console.WriteLine("Task on thread 0 finished.", Thread.CurrentThread.ManagedThreadId);
    );
    Console.WriteLine("this is the main thread");

注意:以上 sn-p 仅用于探索Tasks,因此不能在生产环境中使用。简单地在问题代码 sn-p 中删除 Task 的使用在功能上是等效的,但是此解决方案旨在说明如何使用 Task

【讨论】:

await 运算符只能与异步 lambda 表达式一起使用。没有异步就不会编译这段代码。 等待Task.Run 有什么意义?您可以删除该代码,它会运行相同的。 @Enigmativity 问题的第一句话解释说:我正在尝试理解 C# 中的任务和并行性。. @Enigmativity - 为您的问题提供理由“等待Task.Run 有什么意义?”。学习、理解和探索Tasks @Enigmativity - 很公平,感谢您的建议。答案更新,免责声明意图纯粹是教育性的。【参考方案2】:

您需要等待任务完成。而 3000 相当于 3 秒……不是 3 毫秒。

Task task = new Task(() =>
            
                System.Console.WriteLine("Task on thread 0 started.",
                Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(3000);
                System.Console.WriteLine("Task on thread 0 finished.",
                Thread.CurrentThread.ManagedThreadId);
            );

            task.Start();
            
            System.Console.WriteLine("this is the main thread");
            task.Wait();

【讨论】:

是的,你是对的,它是 3 秒,但它没有打印,正如你在输出窗口中看到的那样谢谢!! @sabin 代码已编辑。您需要根据您的要求调整 task.wait()。 我找不到@StephenCleary 关于手工艺Tasks 的文章。但不建议手动调用 Task ctor。首选方式是Task.RunTask.Factory.StartNew

以上是关于Sleep() 方法后的代码片段没有被执行的主要内容,如果未能解决你的问题,请参考以下文章

如何通过代码设置片段标签?

1 代码片段1

Android 片段生命周期

执行代码时有时不显示对话框片段

getPageTitle() 没有被片段内的 Tablayout 调用

ASP.net MVC 代码片段问题中的 Jqgrid 实现