【问题标题】:How do I change from gui thread to a background thread?如何从 gui 线程更改为后台线程?
【发布时间】:2015-03-04 10:12:50
【问题描述】:

我有一个 GUI,只有 1 个后台线程(不断运行)。 GUI 必须能够告诉 bg 线程在其工作之间执行一些操作。就像 GUI 线程在空闲时可以工作一样。我知道正常线程不会空闲。不过我需要知道:这里有哪些可能性?

当你有一个控件时,切换到一个 GUI 线程很简单:

if (InvokeRequired)
    this.Invoke(new Action<string>(thisMethod), new object[] { text });
else
{
    // ...
}

现在 - 当用户点击一个按钮时 - 我如何在后台线程上执行一个方法已经在运行?通过后台线程,我指的是这些人:

  • new Thread(new ThreadStart(MyThread.Run)).Start();
  • ThreadPool.QueueUserWorkItem(o =&gt; { MyThread.Run(); });

我对这两个都感兴趣:Invoke 和 BeginInvoke 样式。

感谢您的帮助!

【问题讨论】:

  • Task.Run( () =&gt; { })
  • 你几乎不应该使用new Thread。坚持使用线程池,创建线程非常昂贵。
  • 除非目标线程合作,否则不可能在特定线程上运行代码。它必须解决producer-consumer problem。其通用解决方案是线程安全队列和从该队列检索调用请求的调度程序循环。也许这开始听起来很熟悉,是的,这就是 GUI 线程的操作方式。当然在.NET 中得到很好的支持。你喜欢 BeginInvoke(),你might as well use it

标签: c# multithreading winforms invoke


【解决方案1】:

创建一个被后台线程偷看的队列。 如果队列中有一个对象,则为该对象执行工作,否则执行(部分)它自己的工作。

让 GUI 线程将工作放入队列中。

确保队列是线程安全的

【讨论】:

    【解决方案2】:

    你可以使用

    public void test()
    {
        ThreadPool.QueueUserWorkItem(_ => Background("test"));
    }
    

    或者你可以使用

    public void test()
    {
        Parallel.Invoke(() => Background("test"));
    }
    

    或者像这样

    public void test()
    {
        BackgroundDelegate c = new BackgroundMethodDelegate(Background);
        IAsyncResult a = c.BeginInvoke("test", null, null);
        c.EndInvoke(a);
    }
    

    或者像这样

    public void test()
    {
        Thread thread = new Thread(_ => Background("test"));
        thread.Start();
        thread.Join();
    }
    

    有很多不同的方法可以做到这一点

    编辑:

    最简单的方法是使用后台工作人员

    var bw = new BackgroundWorker();            
    bw.DoWork += (worker, args) => {
        Background("test");
    };
    bw.RunWorkerAsync();
    

    在这种情况下,您可以轻松地重用后台工作人员

    如果需要,您甚至可以向其中添加队列 Creating BackgroundWorker with Queue

    【讨论】:

    • 我可能问得模棱两可,请看我的编辑。对不起。我不想产生线程。我有一个后台线程,我需要重用它。
    • @Bitterblue 你的意思是你想要某种“线程”的“池”,它允许你重用里面的“线程”?我想你可能想实现一个ThreadPool
    • @Aron 不,我只有 一个 后台线程。我不想重置它。我想将操作“挤进”它的工作中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    • 2015-05-10
    • 2014-02-21
    相关资源
    最近更新 更多