Winform 异步调用一个方法
在进行Winform开发时,我们都知道经常会用到异步掉一个方法。我们除了可以新启动一个线程外,还可以通过Delegate.BeginInvoke(或Invoke),来实现方法的异步调用。
但以上两种异步方式调用方法,如果方法中有关于界面的操作,比如改变界面某一个控件的属性值,这时候就会报错(线程间操作无效: 从不是创建控件“label1”的线程访问它。)意思是,控件的属性只有主线程可以更改它的值。 这时我们可以通过 Conctrol.BeginInvoke来实现界面控件的属性值更改。
演示代码:
public Form1() { InitializeComponent(); } //要进行异步的方法 private string MethodName(int num, out int ret) { ret = num;
this.Invoke(new MethordDelegate(delegate
{
lbl.text = "正在异步调用该方法;
}));
return "HelloWorld"; } //定义与方法同签名的委托 private delegate string DelegateName(int num, out int ret); //回调方法(异步完成时,执行的方法,此方法只有IAsyncResult一个参数,但是该参数几乎万能,可以传递Object) private void CallBackMethod(IAsyncResult ar) { DelegateName dn = (DelegateName)ar.AsyncState; int i; string r = dn.EndInvoke(out i, ar);//一定要EndInvoke,否则你的下场很惨 this.Invoke(new MethordDelegate(delegate
{
lbl.text = "异步完成了!i的值是"+i.ToString()+",r的值是"+r;
})); } private void Form1_Load(object sender, EventArgs e) { //实例化委托并初赋值 DelegateName dn = new DelegateName(MethodName); int i; //实例化回调函数,把AsyncCallback看成是Delegate就懂了,实际上AsyncCallback是一种特殊的Delegate AsyncCallback acb = new AsyncCallback(CallBackMethod); //异步开始 //如果参数acb换成null则表示没有回调方法 //最后一个参数dn的地方,可以换成任意对象,该对象可以被回调方法从参数中获取出来,写成null也可以。
//参数dn相当于该线程的ID,如果有多个异步线程,可以都是null,但是绝对不能一样,不能是同一个object,否则异常
IAsyncResult iar = dn.BeginInvoke(1, out i, acb, dn); }