【问题标题】:Control.Refresh() Across ThreadsControl.Refresh() 跨线程
【发布时间】:2010-10-11 14:09:46
【问题描述】:

好的,请忽略之前的内容。我不再收到错误,所以我的问题似乎是当我更改图表数据绑定的值时更新图表。

//这里忽略下面

大家好。我有一个 WinForms 应用程序,它有一个面板 panel1。后台线程创建一些其他控件,然后像这样添加到panel1

panel1.Controls.AddRange(myArrayOfControls);

这很好用,我可以看到我的控件被添加了。但是,当新数据进入另一个线程时,我会更新控件父对象中的值,然后需要 Refresh() 以使显示更新为新值。在任一上下文中调用Refresh(),数据进入的线程或接收更新数据的对象都会导致 InvalidOperation 异常,因为需要调用。我已经尝试在我的模型对象以及数据传入的线程中使用 Invoke 并且似乎无法消除错误。

如果有人能提供一些指导,我将不胜感激。

更新:这里有更多信息。我不认为它会需要它,但我错了。 :)

我有一个对象类 MyObject。这个 MyObject 类是在一个名为 topologyThread 的线程中创建的。数据来自 dataThread。 MyObject 的实例有一个 Panel 实例变量,并且 Panel 有子控件,包括来自 System.Windows.Forms.DataVisualization.Charting 命名空间的两个图表。因此,当数据进入 dataThread 时,我会更新 MyObject 对象中的相应数据值,然后需要刷新图表以显示更新后的数据。

我知道数据处理得很好。在我的 MyObject 类中,我将新值记录到属性设置器中的 Console 中,并看到新值显示出来。

【问题讨论】:

    标签: c# .net multithreading controls


    【解决方案1】:

    您必须从主 UI 线程执行这两项操作(刷新和更新控件的父对象)。如果您正在从后台线程修改控件并且没有遇到异常,那是倒霉的,因为这绝对是一个错误。

    最好的方法是使用

    theControl.Invoke(new MethodInvoker(MyUpdateMethod));
    

    如果您有更新如何完成的示例,我们可以提供更好的示例,说明如何从后台线程正确调用它。

    【讨论】:

      【解决方案2】:

      JaredPar 是一个很好的答案。我想补充一点你的代码起作用的原因。

      使用 Windows 窗体,您可以从其他线程与 UI 线程对话。在所有情况下,这都是非常糟糕的做法。

      要注意的是,当你这样做时,很难捕捉到,因为有时 UI 会像没有任何问题一样工作。项目将被添加或更改,并且 UI 将反映更改。但是其他时候运行相同的确切代码,它将无法正常工作。

      这就是从除 UI 线程之外的任何线程触摸 UI 的问题。结果不一致,这就是为什么是非常糟糕的做法。

      上帝,我希望我能发表评论。 :)

      【讨论】:

        【解决方案3】:

        JaredPar 的回答很好。在某些情况下,它可能会导致问题(尤其是在表单构建完成之前调用该方法时)。这是一个更健壮的实现(使用扩展方法)

        public static class ControlInvokeExtensions
        {
            public static void InvokeOnHostThread(Control host, MethodInvoker method)
            {
                if (IsHandleCreated)
                    Invoke(new EventHandler(delegate { method(); }));
                else
                    method();
            }
        }
        

        现在你可以这样称呼它

        panel1.InvokeOnHostThread(() => panel1.Controls.AddRange(myArrayOfControls));
        

        或者如果你是这样的:

        InvokeOnHostThread(() => panel1.Controls.AddRange(myArrayOfControls));
        

        【讨论】:

          猜你喜欢
          • 2014-08-15
          • 1970-01-01
          • 1970-01-01
          • 2012-04-14
          • 2023-03-12
          • 2011-03-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多