【问题标题】:GUI update when starting event handler class on separate thread?在单独的线程上启动事件处理程序类时 GUI 更新?
【发布时间】:2010-10-17 22:27:01
【问题描述】:

我们有一个 DLL,用于监控状态变化并从单独的购买产品中查找事件。实际上,它是 Siemens 的 ScreenPop API,对于那些可能知道它是什么的人来说。我使用 C#.NET 3.5 作为平台。

这个 API 需要很长时间来初始化,所以我们想使用一个单独的线程来初始化它。目前,我们在一个名为 ScreenPop 的类中拥有该功能。该类监控 2 个事件,一个状态更改事件和一个屏幕弹出事件(告诉我们正在呼叫的客户是谁的数据)。

目前实现的方式不起作用,或者至少不能可靠地工作。在 ScreenPop 类中,有一个初始化方法,用于放置所有长时间运行的启动代码。这是从类的构造函数中调用的,如下所示:

public ScreenPop( string Address, int Ext, CallbackStatusType pStatusFunc,
      CallbackScreenPopType pPopFunc 
)
{
    CallbackStatus = pStatusFunc;
    CallbackPopup = pPopupFunc;

    Thread t = new Thread( StartInBackground );
    t.Start();
}

在 GUI 代码中,pStatusFunc 处的 func 更新状态标签,pPopupFunc 处的 func 将触发一些其他代码来执行屏幕弹出 - 现在它只显示来自事件的数据。

缺少很多胶水,但我希望你明白这一点。这种方法的问题是 GUI 没有更新。我知道事件触发并且事件处理程序运行,并且回调函数被调用并且它们似乎应该运行,但 GUI 从未更新。

所以,我的问题是,我应该放弃这个以支持 BackgroundWorker 方法吗?还是我只是在更新 GUI 时遗漏了什么?

应要求提供更多信息... 谢谢, 戴夫

【问题讨论】:

  • 你能添加更多代码吗?api是什么样的?

标签: c# .net multithreading user-interface


【解决方案1】:

您永远不能从其他线程更新 GUI - 只能从启动应用程序的 UI 线程更新。您需要使用 Control.Invoke 方法在 UI 线程上运行代码。表单实例,frmMain.Invoke。

【讨论】:

  • 谢谢。我不知道为什么它逃脱了我,但我无法获得正确的语法来保存我的 ******。
【解决方案2】:

您不能在多线程单元中使用WinForms,要解决此问题,您必须编组到 UI 线程以对其执行操作或获取结果。由于您使用的是 C#3.5,因此您可以利用 lambda、泛型和扩展方法来制作一个非常干净且易于使用的解决方案。

public static class ControlExtensions
{
  public static TResult InvokeEx<TControl, TResult>(this TControl control,
                            Func<TControl, TResult> func)
    where TControl : Control
  {
    if (control.InvokeRequired)
    {
      return (TResult)control.Invoke(func, control);
    }
    else
    {
      return func(control);
    }
  }
}

现在您可以安全轻松地进行更改或获取值。

this.InvokeEx(f => f.label1.Text = "Hello from another thread");

new Thread(() =>
  {
    string formTitle = this.InvokeEx(f => f.Text); // Safely get form title
  }).Start();

【讨论】:

  • 这很漂亮,好吧。太糟糕了,我还没有跟上 lambdas、泛型和扩展方法的速度,所以你在这里所拥有的对我来说意义不大......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 2016-09-08
相关资源
最近更新 更多