【问题标题】:Difference between Thread, ThreadPool & BackgroundWorker [closed]Thread、ThreadPool 和 BackgroundWorker 之间的区别 [关闭]
【发布时间】:2014-03-12 03:16:23
【问题描述】:

我在线程的帮助下多次调用方法

static void Main( string[] args )
{
    Thread t = new Thread( MyFunction );
    t.Start();
}

static void MyFunction()
{
    //code goes here
}

有时我也喜欢使用ThreadPool

System.Threading.ThreadPool.QueueUserWorkItem(delegate {
    MyFunction();
}, null);

但我不明白借助线程类或ThreadPool 类调用任何方法有什么区别

所以我正在寻找一个关于 Thread 和 ThreadPool 类之间有什么区别的很好的讨论。还需要知道我们何时应该使用 Thread 类调用方法以及何时使用 ThreadPool 类调用任何方法?如果可能的话,还与示例情况讨论示例代码。

另一个非常重要的问题是,如果我启动多个线程,那么我的应用程序性能会变低还是变差?如果是,那么告诉我为什么...?

现在还告诉我什么是 BackgroundWorker 类以及它与 Thread 和 ThreadPool 类有何不同。我听说BackgroundWorker 类还创建了一个单独的线程来运行任何方法。所以请讨论它与 Thread 和 ThreadPool 类有何不同,以及何时应该选择 BackgroundWorker 类。

这里是BackgroundWorker的小示例代码

private void button1_Click(object sender, EventArgs e)
    {
        BackgroundWorker bw = new BackgroundWorker();

        // this allows our worker to report progress during work
        bw.WorkerReportsProgress = true;

        // what to do in the background thread
        bw.DoWork += new DoWorkEventHandler(
        delegate(object o, DoWorkEventArgs args)
        {
            BackgroundWorker b = o as BackgroundWorker;

            // do some simple processing for 10 seconds
            for (int i = 1; i <= 10; i++)
            {
                // report the progress in percent
                b.ReportProgress(i * 10);
                Thread.Sleep(1000);
            }

        });

        // what to do when progress changed (update the progress bar for example)
        bw.ProgressChanged += new ProgressChangedEventHandler(
        delegate(object o, ProgressChangedEventArgs args)
        {
            label1.Text = string.Format("{0}% Completed", args.ProgressPercentage);
        });

        // what to do when worker completes its task (notify the user)
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
        delegate(object o, RunWorkerCompletedEventArgs args)
        {
            label1.Text = "Finished!";
        });

        bw.RunWorkerAsync();
    }

【问题讨论】:

  • 这对Stack Overflow 来说不是一个好问题。这是一本书的信息。
  • 创建线程是一项昂贵的操作。大约要创建 200,000 个循环,完成后需要 100,000 个循环。建议使用预先创建的线程(例如 ThreadPool)。当您需要从 UI 线程卸载处理并且仍然需要进度/取消时使用 BackgroundWorker - 或使用 Task.
  • 线程是您的经典线程,只是创建一个新工作并在新线程中运行它。线程池是一种管理您创建的线程数量的方法。例如,创建一个 10 个线程的线程池,从池中获取一个,执行一些作业,将其放回池中以备后用。 BackgroundWorker 类通过设置 UI 线程的挂钩来帮助更新您的应用程序。由于您只能在主 UI 线程上更改 UI,因此 RunWorkerCompletedEventHandler 和 ProgressChangedEventHandler 在 UI 线程上执行,因此您不必担心先查找它。
  • @Mou:你可能会发现an old blog post of mine很有用。

标签: c# multithreading backgroundworker threadpool


【解决方案1】:

但我不明白在线程类或线程池类的帮助下调用任何方法有什么区别

主要区别在于您是自己管理线程生命周期 (Thread),还是利用框架已经创建的线程“池”。

使用ThreadPool.QueueUserWorkItem 将(经常)使用系统中已经存在的线程。这意味着您没有启动新线程的开销 - 相反,一组线程已经存在,您的工作只是在其中一个上运行。如果您正在执行许多短期操作,这可能特别有用。

当您使用new Thread 时,您实际上启动了一个新线程,该线程将一直存在到您的委托完成其执行。

请注意,从 .NET 4 和 4.5 开始,我建议使用 TaskTask&lt;T&gt; 类型,而不是创建自己的线程或使用 ThreadPool.QueueUserWorkItem。这些(默认情况下)使用线程池执行,但提供了许多其他有用的抽象,尤其是 C# 5 和 await/async 关键字。

现在还告诉我什么是 BackgroundWorker 类以及它与 Thread 和 ThreadPool 类有何不同。 h

BackgroundWorker 类是对线程池的抽象。它使用ThreadPool 来排队“工作”(您的DoWork 事件处理程序),但还提供额外的功能,允许将进度和完成事件发送回初始SynchronizationContext(在GUI 程序中,通常是用户界面线程)。这简化了您想要更新 UI 以获取进度或完成通知的任务,因为后台“工作”正在后台线程上运行。

【讨论】:

  • 很好奇为什么这里投票不赞成...... :)
  • 我猜所有的线程类都是默认的前台线程但是BackgroundWorker只处理后台线程......为什么?如果可能,请提供有关前台和后台线程的一些见解。
  • @Thomas 线程池使用后台线程。一般来说,这就是人们想要的——获得前台线程的唯一方法就是自己制作。
  • 线程 t = 新线程(MyFunction); t.Start();当我们使用线程类创建线程时,创建的默认线程类型是什么......是后台还是前台??
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-09
  • 2013-01-04
  • 1970-01-01
  • 2012-07-30
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
相关资源
最近更新 更多