【问题标题】:Multi-threaded multi-windowed application not working多线程多窗口应用程序不起作用
【发布时间】:2011-07-31 08:23:09
【问题描述】:

我想创建一个进行远程安装的程序。我希望能够在每次安装开始时启动一个窗口,并提供一个包含工作大致进度的进度条。

如果我在主线程之外创建窗口,我可以访问它的所有元素,但由于实际运行安装的任务,它没有响应。如果我在新线程中启动窗口,我似乎无法让主线程识别窗口中的任何元素,因此我无法更新进度条。

如何创建响应式的多线程 UI?

【问题讨论】:

  • 刚刚进行了比平时更重的编辑,但摆脱了闲聊。我希望我留下的是真正的问题。
  • 顺便说一句,我认为这是一个 WinForms 应用程序而不是 WPF?

标签: c# winforms multithreading


【解决方案1】:

要使 UI 响应第二个线程(正在执行工作)并能够从第二个线程更新 UI,您需要在控件上使用 Invoke。那里有许多可用的代码 sn-ps。

这是一个简短的例子:How can I update my user interface from a thread that did not create it?

您也可以在这里找到数十个关于 SO 的示例 - 只需进行搜索 :)

这是今天关于 SO 的另一个类似问题 - cross threading problem - 其中一个答案中有一个代码示例。

【讨论】:

    【解决方案2】:

    有一种简单的方法可以安全地从其他线程访问 UI 控件 - 使用 Control.BeginInvoke(lambda) 方法调用 lambda。例如,假设您的 WinForms 应用程序带有一个表单和带有按钮的进度条。单击按钮时 - 一些虚构的工作正在单独的线程中进行,并且应该更新进度条。最简单的就是这样写:

    private void button1_Click(object sender, EventArgs e)
    {
        ThreadStart s = () =>
        {
            for (int i = 0; i <= 10; i++)
            {
                Action a = () => progressBar1.Value = i * 10;
                BeginInvoke(a);
                Thread.Sleep(300); // imitate some workload
            }
        };
        var t = new Thread(s);
        t.Start();
    }
    

    使用BackgroundWorker 或其他技术也可以达到相同的效果,但对我来说这是最简单的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-26
      • 1970-01-01
      • 2020-05-24
      • 2020-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多