【问题标题】:C# Threads and this.Invalidate()C# 线程和 this.Invalidate()
【发布时间】:2009-03-03 18:58:01
【问题描述】:

我正在开发一个 Windows Mobile 应用程序(Compact Framework 2.0 SP1),这段代码给我一个错误:

public Image Imagen { get { return imagen; } set { imagen = value; this.Invalidate(); } }

代码是从一个新线程调用的。我尝试使用 **InvokeRequired 解决:

public Image Imagen { get { return imagen; } set { imagen = value; if (this.InvokeRequired) this.Invoke(this.Invalidate); else this.Invalidate(); } }

但是 this.Invoke(this.Invalidate); 行无法编译。我该如何解决这个问题?第一个错误是您可以与在另一个线程上创建的控件进行交互。

谢谢!

【问题讨论】:

    标签: c# winforms multithreading graphics


    【解决方案1】:

    Invalidate 不需要调用。

    invalidate 只包含一条要由主线程处理的绘制消息以及其余未决消息。但是当你调用invalidate时绘制并没有完成,并且控件没有被这个线程改变,所以你不需要为它使用invoke。

    如果需要确保控件刷新,可能invalidate还不够,还需要调用update。

    【讨论】:

      【解决方案2】:

      试试这个。

      为什么这是必要的冗长版本。 Invoke 方法不采用特定的 Delegate 类型作为参数,而是采用 System.Delegate 类型。此类型不提供强类型签名的类型。它是基委托类,而是提供了一种通用机制来调用所有委托。

      不幸的是,当在 C# 中将方法名称作为委托源传递时,它必须传递给特定的委托类型。否则,C# 不知道要在后台创建什么类型的委托,并且与 VB 不同,它不会生成匿名委托类型。这就是为什么您需要像 MethodInvoker 这样的特定委托类型才能调用该函数的原因。

      编辑手动定义 MethodInvoker,因为它在 Compact Framework 中不存在

      public delegate void MethodInvoker();
      
      public Image Imagen
      {
          get { get return imagen; }
          set {
              imagen = value;
              if (this.InvokeRequired)
                  this.Invoke(new MethodInvoker(this.Invalidate));
              else
                  this.Invalidate();
          }
      }
      

      【讨论】:

      • 这个 Winform 是为 windows mobile 设计的,所以我使用的是没有 methodinvoker 的 Compact Framework。
      【解决方案3】:

      Invoke 函数需要一个委托,因此您可以使用内置的 Action 委托:

      public Image Imagen
      {
          get
          {
              return imagen;
          }
          set
          {
              imagen = value;
              if (this.InvokeRequired)
                  this.Invoke(new Action(this.Invalidate));
              else
                  this.Invalidate();
          }
      }
      

      【讨论】:

      • @VansFannel,System.Action(无泛型)已添加到 .Net 3.5
      【解决方案4】:

      Compact Framework 2.0 SP1 的解决方案是这样的:

      ... delegate void InvocadorMetodos(); ... public Image Imagen { get { return imagen; } set { imagen = value; if (this.InvokeRequired) { InvocadorMetodos invalida = Invalidar; this.Invoke(invalida); } else this.Invalidar(); } }

      谢谢!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-01
        • 2015-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-30
        • 2011-06-15
        相关资源
        最近更新 更多