现在编程里多线程是常用的,而vs2005中如果有一个控件,又不能在非创建它的线程中修改它的属性,那就必须用委托。
    public delegate void ShowInformation(string str);//显示信息
        /// <summary>
        /// 显示信息
        /// </summary>
        void ShowInfo(string StrInfo)
        {
            Invoke(new ShowInformation(OnshowInformation), StrInfo);
        }
        void OnshowInformation(string StrInfo)
        {
           lblInfo.Text = StrInfo;
           lblLocalVer.Text =Convert.ToString ( LocalVer);
           lblServerVer.Text =Convert .ToString( ServerVer);
           lblFilesCount.Text = Convert.ToString(intFilesCount);
        }要是这样的控件多了,不是麻烦了吗???

解决方案 »

  1.   


    应该只是不能修改于外观相关的属性值吧,这样没办法,线程安全本来就.NET的一个特性来的
      

  2.   

    以前常听高手告诫MFC对象不要跨线程使用,因为MFC不是线程安全的。比如CWnd对象不要跨线程使用,可以用窗口句柄(HWND)代替。CSocket/CAsyncSocket对象不要跨线程使用,用SOCKET句柄代替.那么到底什么是线程安全呢?什么时候需要考虑?如果程序涉及到多线程的话,就应该考虑线程安全问题。比如说设计的接口,将来需要在多线程环境中使用,或者需要跨线程使用某个对象时,这个就必须考虑了。关于线程安全也没什么权威定义。在这里我只说说我的理解:所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。 
        一般而言“线程安全”由多线程对共享资源的访问引起。如果调用某个接口时需要我们自己采取同步措施来保护该接口访问的共享资源,则这样的接口不是线程安全的.MFC和STL都不是线程安全的. 怎样才能设计出线程安全的类或者接口呢?如果接口中访问的数据都属于私有数据,那么这样的接口是线程安全的.或者几个接口对共享数据都是只读操作,那么这样的接口也是线程安全的.如果多个接口之间有共享数据,而且有读有写的话,如果设计者自己采取了同步措施,调用者不需要考虑数据同步问题,则这样的接口是线程安全的,否则不是线程安全的。 
      

  3.   

    MFC对象不要跨线程使用,因为MFC不是线程安全的。
    有此一说,因为HWND与CWnd*之前的转换用到了一个TLS的MAP.
      

  4.   

    在VS2003中,也不能直接访问,参看
    一般来说,直接在子线程中对窗体上的控件操作是会出现异常,这是由于子线程和运行窗体的线程是不同的空间,因此想要在子线程来操作窗体上的控件,是不可能简单的通过控件对象名来操作,但不是说不能进行操作,微软提供了Invoke的方法,其作用就是让子线程告诉窗体线程来完成相应的控件操作。 现在用一个用线程控制的进程条来说明,大致的步骤如下:1.  创建Invoke函数,大致如下:        /// <summary>        /// Delegate function to be invoked by main thread        /// </summary>        private void InvokeFun()        {            if( prgBar.Value < 100 )                prgBar.Value = prgBar.Value + 1;        } 2.  子线程入口函数:        /// <summary>        /// Thread function interface        /// </summary>        private void ThreadFun()        {            //Create invoke method by specific function            MethodInvoker mi = new MethodInvoker( this.InvokeFun );             for( int i = 0; i < 100; i++ )            {                this.BeginInvoke( mi );                Thread.Sleep( 100 );            }        } 3.  创建子线程:            Thread thdProcess = new Thread( new ThreadStart( ThreadFun ) );            thdProcess.Start();        备注:              using System.Threading;              private System.Windows.Forms.ProgressBar prgBar;     运行后的效果如下图所示:
      

  5.   

    加入该句:Control.CheckForIllegalCrossThreadCalls = False
    取消线线程安全保护模式!
      

  6.   

    线程安全的概念其实很简单,如果一个类没有私有成员变量,那么他就是绝对线程安全的。线程安全的问题主要出在类的私有成员变量上。
    举个很简单的例子
    private int _i;public void MethodA( int i )
    {
      _i = i;
      //处理......
      MethodB();
      //......
    }private void MethodB()
    {
      int k = _i;//冲突发生在这里。
    }
    如果两个线程同时调用MethodA,那么_i的值就不可预测,导致MethodB的行为也不可预测,这就是线程冲突……
      

  7.   

    先谢谢大家!关于线程安全我是知道的,我只是想说:在多线程中每设置一个控件的属性都要Invoke有点烦,代码也不整洁。Knight94(愚翁) 的方法不错,不过好象带参数:-)AgainWarning() 说的:
    加入该句:Control.CheckForIllegalCrossThreadCalls = False
    取消线线程安全保护模式!
    这会使控件以与在 Visual Studio 2003 下相同的方式运行。
    如果在vs2003中用的很坦然,到vs2005中把这个手动取消了,总觉得有点...
      

  8.   

    各位搞软件开发(.NET  SQL JAVA C++ 等)的朋友有兴趣可能加
    18144686
    在这里我们真正的做到只讨论技术!
    做广告者勿扰!谢谢!