C#Threads和this.Invalidate()

时间:2009-03-03 18:58:01

标签: c# winforms multithreading graphics

我正在开发 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); 这一行无法编译。我该如何解决这个问题?第一个错误是您可以与在另一个线程上创建的控件进行交互。

谢谢!

4 个答案:

答案 0 :(得分:7)

Invalidate不需要调用。

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

如果您需要确保刷新控件,可能是invalidate不够,您也需要调用更新。

答案 1 :(得分:3)

试试这个。

为什么这是必要的长篇版本。 Invoke方法采用System.Delegate类型,而不是将特定的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();
    }
}

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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();

            }
        }


谢谢!