是否将任务创建为后台线程?


85

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

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

我无法在MSDN上找到有关此文件的任何文档:-(

Answers:


119

验证并不难:

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

答案是...

ǝnɹʇ


我遇到了所有任务都在调用线程上运行的问题。我将上面精确的代码行粘贴到我的项目中,并报告“ false”。你知道为什么会这样吗?我正在使用.NET 4.0。
Trevor Elliott

8
根据该线程stackoverflow.com/questions/7889746/…,不能保证在启动任务时有后台线程,但如果使用TaskCreationOptions.LongRunning,则应保证是后台线程。我正在使用该选项,但它仍未创建后台线程。是什么赋予了?
Trevor Elliott

可以将其配置为不吗?
罗伊·纳米尔

2
我相信Moozhe的问题可能在于默认的同步上下文。取决于您在WinForms,WPF,Web还是控制台应用程序中,您的行为可能会有所不同,因为它们都具有调度并发任务的默认方式。
jpierson

5
爱你的答案:“ǝnɹʇ”。很好玩 谢谢。
泰迪

12

如果您开始Task<T>使用Task.Run(),则可以。

如果使用asyncawait,则否。从这里摘录:

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


1
由于您正在使用Task.Run,​​它将在后台线程上运行,但是如果它等待着等待,那么它可能会做一些特殊的事情来暂停线程并等待结果。值得调查。
Steztric


0

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


-1

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

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

获取运行时异常:

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

就像使用良好的旧常规背景线程一样。

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

处理此问题的最佳方法是启动一个后台线程 ,该线程使用Task.Run进行工作,并等待其结果。这将使UI在完成工作时感觉流畅。

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


您的检查仅确认任务在其自己的线程中运行,而不确认该线程是后台线程。后台线程是一个即使仍在执行也不会阻止程序终止的线程。
索伦Kuklau
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.