日期:2014-05-18  浏览次数:20746 次

请教关于多线程操作控件的问题。
请教关于多线程操作控件的问题。

平时在多线程中操作界面控件,都是适应invoke委托来进行相关操作的,但是最近发现一个现象是,在label控件中,如果直接对label的text赋值会触发异常,但是对label的background赋值则不会,此想象还存在的picturebox中,在线程中对其image赋值可以不用使用委托。

我操作的控件的方法是由其他线程的中的事件触发的。 请高手指教这是什么原因,给下具体的说明或文档。谢谢

------解决方案--------------------
跨线程禁止访问主要是避免对Handle的错误访问,那么在设置Text时,会调用以下方法
C# code

   System.Windows.Forms.Control.get_Handle()
   System.Windows.Forms.Control.set_WindowText(String value)
   System.Windows.Forms.Control.set_Text(String value)
   System.Windows.Forms.Label.set_Text(String value)
在 set_WindowText 方法中通过
UnsafeNativeMethods.SetWindowText(new HandleRef(this.window, this.Handle), value);
去设置Text,这里要访问Handle,确保Handle正确,就会使用get_Handle,代码如下


public IntPtr get_Handle()
{
//这里会检查
    if ((checkForIllegalCrossThreadCalls && !inCrossThreadSafeCall) && this.InvokeRequired)
    {
        throw new InvalidOperationException(SR.GetString("IllegalCrossThreadCall", new object[] { this.Name }));
    }
    if (!this.IsHandleCreated)
    {
        this.CreateHandle();
    }
    return this.HandleInternal;
}

设置BackGroundImage时,代码中不需要检查Handle
public virtual Image BackgroundImage
{
    get
    {
        return (Image) this.Properties.GetObject(PropBackgroundImage);
    }
    set
    {
        if (this.BackgroundImage != value)
        {
            this.Properties.SetObject(PropBackgroundImage, value);
            this.OnBackgroundImageChanged(EventArgs.Empty);
        }
    }
}