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 去调用,两者的区别就是一个导致工作线程等待,而另外一个则不会。