C#中的Invoke和BeginInvoke

一、关于Invoke和BeginInvoke
   有一篇文章说通过BeginInvoke给线程函数传参数,如下
class ThreadOperation
    {
        public delegate void myDelegate(int count, string str);
        public void StartThread()
        {
            myDelegate dele = new myDelegate(Func2);
            dele.BeginInvoke(1, "test");
        }

        public void Func2(int count, string str)
        {
            Console.WriteLine(string.Format("{0}:{1}", Thread.CurrentThread.ManagedThreadId, str));
            Thread.Sleep(1000);
        }
    }

这种方法是正确的,使用异步委托,修改程序如下;
 class ThreadOperation
    {
        public delegate void myDelegate(int count, string str);
        public void StartThread()
        {
            myDelegate dele = new myDelegate(Func2);
            dele.BeginInvoke(1, "test", new AsyncCallback(AfterMyMothod3), null);
        }

        public void Func2(int count, string str)
        {
            while (true)
            {
                Console.WriteLine(string.Format("{0}:{1}", Thread.CurrentThread.ManagedThreadId, str));
                //Thread.Sleep(1000);
            }
        }

        public void AfterMyMothod3(IAsyncResult result)
        {
            //AsyncResult async = (AsyncResult)result;
            //MyMethod3Delegate DelegateInstance = (MyMethod3Delegate)async.AsyncDelegate;
            //Console.WriteLine("函数调用返回值:{0}\n", DelegateInstance.EndInvoke(result));
        }

    }
但是为什么总跳出来呢?

 

 

    一般来说,直接在子线程中对窗体上的控件操作是会出现异常,这是由于子线程和运行窗体的线程是不同的空间,因此想要在子线程来操作窗体上的控件,是不可能简单的通过控件对象名来操作,但不是说不能进行操作,微软提供了Invoke的方法,其作用就是让子线程告诉窗体线程来完成相应的控件操作。
    在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法。

    Invoke 和 BeginInvoke 就是为了解决这个问题而出现的,使你在多线程中安全的更新界面显示。

    正确的做法是将工作线程中涉及更新界面的代码封装为一个方法,通过 Invoke 或者 BeginInvoke 去调用,两者的区别就是一个导致工作线程等待,而另外一个则不会。

posted @ 2010-12-16 17:39  pjh123  阅读(276)  评论(0编辑  收藏  举报