【问题标题】:Are Tasks created as background threads?任务是作为后台线程创建的吗?
【发布时间】:2011-03-06 08:58:12
【问题描述】:

我只是想知道 dot.net 4 中的新任务类是创建后台线程还是前台线程?

通常我会在线程上设置“IsBackground”,但在任务上没有这样的属性。

我在 MSDN 上找不到任何相关文档 :-(

【问题讨论】:

    标签: c#-4.0


    【解决方案1】:

    应该不难验证:

    class Program
    {
        static void Main()
        {
            Task
                .Factory
                .StartNew(() => Console.WriteLine(Thread.CurrentThread.IsBackground))
                .Wait();
        }
    }
    

    答案是……

    ǝnɹʇ

    【讨论】:

    • 我遇到了一个问题,我的所有任务都在调用线程上运行。我将上面那行精确的代码粘贴到我的项目中,它报告“错误”。你知道为什么会这样吗?我正在使用 .NET 4.0。
    • 根据该线程stackoverflow.com/questions/7889746/…,您不能保证在启动任务时使用后台线程,但如果您使用TaskCreationOptions.LongRunning,则应该如此。我正在使用该选项,但它仍然没有创建后台线程。什么给了?
    • 可以不配置吗?
    • 相信莫哲的问题可能出在默认的同步上下文上。行为可能会有所不同,具体取决于您是在 WinForms、WPF、Web 还是控制台应用程序中,因为它们都有不同的默认调度并发任务的方式。
    • 喜欢你的回答:“ǝnɹʇ”。很有趣。谢谢。
    【解决方案2】:

    如果您使用Task.Run() 启动Task<T>,那么可以。

    如果您使用的是asyncawait,则不需要。摘自here

    “async 和 await 关键字不会导致创建额外的线程。async 方法不需要多线程,因为 async 方法不会在自己的线程上运行。该方法在当前同步上下文上运行并使用时间仅当方法处于活动状态时才在线程上运行。您可以使用 Task.Run 将 CPU 绑定的工作移至后台线程,但后台线程对等待结果可用的进程没有帮助。”

    【讨论】:

    • 由于您使用的是 Task.Run 它将在后台线程上,但如果它遇到等待,那么它可能会做一些特殊的事情来暂停线程并等待结果。值得研究。
    【解决方案3】:

    它似乎作为后台线程运行。

    看到这个帖子:

    Running multiple C# Task Async

    【讨论】:

      【解决方案4】:

      任务由来自系统线程池的线程执行。来自线程池的线程默认在后台执行。

      【讨论】:

        【解决方案5】:

        如果您还不相信后台任务,只需尝试从任务中访问 GUI 元素,例如:

        public async Task<int> ProcessStuff_Async()
        {
            while(true)
            {
                label1.Text = "processing next item";
        

        获取运行时异常:

        跨线程操作无效: 控件“label1”从创建它的线程以外的线程访问。

        就像旧的常规后台线程一样。

        MSDN docs 中有信息(截至 2017 年 :-),例如:

        处理这个问题的最好方法是启动一个后台线程 使用Task.Run 完成工作,并await 结果。这将允许 UI 在工作完成时感觉流畅。

        这个文档甚至有一个部分What happens under the covers

        【讨论】:

        • 您的检查仅确认该任务在其自己的线程中运行,而不是该线程是后台线程。后台线程是一个线程,如果仍在执行,不会阻止程序终止。
        • @SörenKuklau 或今天投票反对我的人:确实我错过了后台线程是一个特殊线程这一点。我现在想知道后台线程的概念是起源于unix还是Windows发明的?
        • @SörenKuklau 我添加了“或任何人”,因为反对票是在过去 7 天内,而您在 3 年前发表了评论。我不担心被否决,但我仍然很好奇阻止应用程序终止的后台线程是否是 Windows 发明。
        猜你喜欢
        • 1970-01-01
        • 2014-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-07
        • 1970-01-01
        • 1970-01-01
        • 2012-06-22
        相关资源
        最近更新 更多