【问题标题】:Winforms should I multi thread or use event timer?Winforms我应该多线程还是使用事件计时器?
【发布时间】:2010-10-11 13:21:30
【问题描述】:

我目前有一个线程来侦听来自网络的数据,然后在其上运行规则。然后我想将数据传递给 GUI。我担心在 GUI 中出现死锁。我不知道将互斥锁放在 GUI 端。我也在使用 c# 和 dotnet 3.5。

我想出的是 1)使用计时器创建事件并转储线程。担心性能。 2) 使用中间事件将数据复制到 GUI。 3) 深入研究并找出使用 GUI 的线程安全方式。

你认为最好的方法是什么?

编辑:这是我正在使用的解决方案。我传入更改的元素,然后用互斥锁保护大对象。我使用辅助函数使用 InvokeRequired 然后 BeginInvoke 与委托切换线程。从阅读答案中提取,然后点击链接,直到通过Jon Skeet 到达Threading in Windows Forms

  delegate void UInt32ParameterDelegate(UInt32 n);

  public void UpdateLocation(UInt32 n)
  {
     if (InvokeRequired)
     {
        // We're not in the UI thread, so we need to call BeginInvoke
        BeginInvoke(new UInt32ParameterDelegate(UpdateLocation), new object[] { n });
        return;
     }
     // Must be on the UI thread if we've got this far

     this.engine.location.UpdateBusy.WaitOne();
     // do the work in here

     this.engine.location.UpdateBusy.ReleaseMutex();

  }

【问题讨论】:

    标签: c# winforms multithreading user-interface


    【解决方案1】:

    Windows 窗体中的同步非常容易。您可以在后台线程中调用 Control.Invoke()。线程将停止,直到委托在 UI 线程上完成运行。根本不需要同步。

    如果停止线程是一个问题,请使用 Control.BeginInvoke()。如果线程在继续运行时可能会更改它们,则必须使用锁保护传递给委托的对象。这在生产者-消费者场景中很少见,线程可以简单地创建新对象。

    请确保您不要过于频繁地调用 ()。执行频率超过每秒 1000 次,UI 线程将停止发送 Windows 消息,并因处理调用请求而陷入困境。由于您要取悦的是人眼,因此每秒调用超过 25 次只是浪费精力。将中间结果池化为一个集合对象。

    【讨论】:

      【解决方案2】:

      希望我能正确理解您的问题。

      在后台线程读取数据并为所欲为之后,它应该使用Invoke 调用GUI 线程上的方法。该方法将更新应在 GUI 中更新的任何内容。

      【讨论】:

        【解决方案3】:

        从不在 GUI 线程上从网络读取。在网络中断期间运行您的应用程序并导致您的 GUI 挂起只是时间问题。这真的会让你的用户感到沮丧。

        在您的情况下,我认为最好的方法是让后台线程完成读取操作。然后获取结果数据并通过SynchronizationContext Post 或Send 方法将其移回GUI 线程。

        【讨论】:

          【解决方案4】:

          您应该将一个事件从您的网络线程传递到您的 UI 线程。

          然后使用 begininvoke 跨线程,这样就不会出现跨线程异常。

          Need help getting info across a UI thread and another thread in C#

          【讨论】:

            【解决方案5】:

            您可以使用backgroundworker 来处理后台线程中的数据读取,完成后您可以结束后台工作程序,触发它的 RunWorkerCompletedEventHandler。在 RunWorkerCompletedEventHandler 中,您可以使用结果更新您的 GUI 线程。

            【讨论】:

              【解决方案6】:

              只抛出一个引发通知表单刷新的事件的委托不是更容易吗?

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-10-21
                • 1970-01-01
                • 2012-04-19
                • 1970-01-01
                • 2011-06-02
                相关资源
                最近更新 更多