我的程序是这样的,在我点击界面上按钮后,执行如下的异步委托:
this.BeginInvoke(new go(toF));
其中“toF”的方法中有操作UI控件的。所以用this.BeginInvoke来执行。但遇到问题是,我用UI的线程来执行toF,那么UI会卡死。但如果不用this.BeginInvoke来执行,那么又不可以跨线程安全操作UI控件。问题1是:我已经用异步BeginInvoke了而不是用Invoke同步,为什么UI还会卡死?异步也阻塞吗?问题2:.NET工具栏的自身的控件是怎么做到不卡死UI界面的?比如listBox这控件,在listBox.Items.Add()的时候界面也是很顺畅的???

解决方案 »

  1.   


    using System.Timers;
     public delegate void AddCheck(string val);//委托
            public int flag = 0;
            void ExecuteWork(object sender, ElapsedEventArgs e)
            {
                flag++;
                this.BeginInvoke(new AddCheck(AddCheckHandler), new object[] { flag.ToString() });
            }
            void AddCheckHandler(string val)
            {
                checkedListBox1.Items.Add(val);
            } System.Timers.Timer tm = new System.Timers.Timer(2000);
                tm.Elapsed += new System.Timers.ElapsedEventHandler(ExecuteWork);
                tm.AutoReset = true;
                tm.Enabled = true;
    以上 代码 没有任何卡的效果啊
      

  2.   

    (1)Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不同的。
    (2)Control的Invoke和BeginInvoke的参数为delegate,委托的方法是在Control的线程上执行的,也就是我们平时所说的UI线程。
      

  3.   

    toF是主线程函数,肯定要阻塞
      

  4.   

    1.BeginInvoke和Invoke只用在非UI线程中
    2.BeginInvoke和Invoke跟阻不阻塞UI线程没关系,是相对于子线程的,前者不阻塞子线程,后者阻塞子线程(这里的子线程是指调用this.Invoke和this.BeginInvoke的线程)
    3.如果你大量操作UI界面,BeginInvoke和Invoke也解决不了界面卡的问题,它两只能解决跨线程访问控件的问题。BeginInvoke和Invoke跟界面卡不卡没有任何关系,这儿的异步是针对子线程而言的。参见 http://bbs.csdn.net/topics/390528065  #8
      

  5.   

    1.看看这篇文章:Invoke 和 BeginInvoke 的真正涵义
    2.一定要把运算时间长的代码放在工作线程中而非UI线程。
      

  6.   

    关键是你toF的执行时间,如果低于500毫秒,就不会感觉卡了,如果时间很长,就和单线程操作差不多了,你不能把所有操作放在一个方法(一个线程里执行),那样就不叫多线程操作了。如果toF里面有大量计算的时间,要分离出来,把最后界面更新部分单独封装,宁可多调用几次BeginInvoke,不要偷懒。
      

  7.   

    嗯,看了很多资料,理解了。要把更新UI的操作单独提取出来,返回给UI线程去执行。
    原来是一开始我对异步和UI线程之间的理解错误,也谢谢楼上各位!