一:异步的回调
首先定义一个有参有返回值的委托,实例化并且异步调用
查看BeginInvoke()的参数,第二个类型为AsyncCallback的参数就是启用回调的参数了,F12发现这个参数本身也是一个有参无返回值的委托。
既然他也是一个委托,那也是需要实例化来调用
得到如下代码
private void button3_Click_1(object sender, EventArgs e)
{
Console.WriteLine("***********************************异步开始***********************************");
rtfunction rt = new rtfunction(lodinglong);
AsyncCallback callback = new AsyncCallback(back);
IAsyncResult AsyncResult = rt.BeginInvoke("异步", "异步", callback, null);
Console.WriteLine("***********************************异步结束***********************************");
}
public void back(IAsyncResult ar)
{
Console.WriteLine("执行回调");
}
private static long lodinglong(string name, string project)
{
Console.WriteLine("这里是{0}开始执行{1},这里是线程{2}", name, project, Thread.CurrentThread.ManagedThreadId); ;
long result = 0;
for (int i = 0; i < 1000000; i++)
{
result += i;
}
Thread.Sleep(2000);//等待2s
Console.WriteLine("这里是{0}结束执行,这里是线程{1},计算结果为{2}", name, Thread.CurrentThread.ManagedThreadId, result); ;
return result;
}
得到的结果如下:可以看出,回调方法是在异步完成之后进行的
二:异步的状态参数
看完了回调,再接着看最后一个参数 obiect。此参数在回调中使用
上一步说到AsyncCallback其实也是一个委托,其中它还有一个类型为IAsyncResult的参数,这个参数就是我们的obiect。F12进去查看IAsyncResult,可以看到以下几种方法,其中AsyncState就是状态参数
在方法里面加入我们的第四个参数并且运行程序,代码如下
private void button3_Click_1(object sender, EventArgs e)
{
Console.WriteLine("***********************************异步开始***********************************");
rtfunction rt = new rtfunction(lodinglong);
AsyncCallback callback = new AsyncCallback(back);
IAsyncResult AsyncResult = rt.BeginInvoke("异步", "异步", callback, "用于回调的");
//lambda写法
//IAsyncResult AsyncResults = rt.BeginInvoke("异步", "异步",
// t => Console.WriteLine("执行回调,状态是{0}", t.AsyncState),
// "用于回调的");
Console.WriteLine("***********************************异步结束***********************************");
}
public void back(IAsyncResult ar)
{
Console.WriteLine("***********************************这里是回调的开始***********************************");
Console.WriteLine("执行回调,状态是{0}", ar.AsyncState);
Console.WriteLine("***********************************这里是回调的结束***********************************");
}
private static long lodinglong(string name, string project)
{
Console.WriteLine("这里是{0}开始执行{1},这里是线程{2}", name, project, Thread.CurrentThread.ManagedThreadId); ;
long result = 0;
for (int i = 0; i < 1000000; i++)
{
result += i;
}
Thread.Sleep(2000);//等待2s
Console.WriteLine("这里是{0}结束执行,这里是线程{1},计算结果为{2}", name, Thread.CurrentThread.ManagedThreadId, result); ;
return result;
}
结果如下
三.异步的返回值
1.使用EndInvoke会卡住当前线程
private void button3_Click_1(object sender, EventArgs e)
{
Console.WriteLine("***********************************异步开始***********************************");
rtfunction rt = new rtfunction(lodinglong);
AsyncCallback callback = new AsyncCallback(back);
//lambda
//IAsyncResult AsyncResult = rt.BeginInvoke("异步", "异步",
// t => Console.WriteLine("执行回调,状态是{0}", t.AsyncState),
// "用于回调的");
IAsyncResult AsyncResult = rt.BeginInvoke("异步", "异步", callback, "用于回调的");
var result = rt.EndInvoke(AsyncResult);//等待异步结束,卡主当前线程
Console.WriteLine("返回的结果是{0}", result);
Console.WriteLine("***********************************异步结束***********************************");
}
public void back(IAsyncResult ar)
{
Console.WriteLine("***********************************这里是回调的开始***********************************");
Console.WriteLine("执行回调,状态是{0}", ar.AsyncState);
Console.WriteLine("***********************************这里是回调的结束***********************************");
}
private static long lodinglong(string name, string project)
{
Console.WriteLine("这里是{0}开始执行{1},这里是线程{2}", name, project, Thread.CurrentThread.ManagedThreadId); ;
long result = 0;
for (int i = 0; i < 1000000; i++)
{
result += i;
}
Thread.Sleep(2000);//等待2s
Console.WriteLine("这里是{0}结束执行,这里是线程{1},计算结果为{2}", name, Thread.CurrentThread.ManagedThreadId, result); ;
return result;
}
划重点!!到这里会发现,程序这时候真正按照我想要的顺序在进行。等待异步完成,异步结束,获取返回值,进行回调。
2.可在回调中使用
//lambda
IAsyncResult AsyncResult = rt.BeginInvoke("异步", "异步",
t =>
{
Console.WriteLine("***********************************这里是回调的开始***********************************");
Console.WriteLine("执行回调,状态是{0}", t.AsyncState);
var result = rt.EndInvoke(t);
Console.WriteLine("返回的结果是{0}", result);
Console.WriteLine("***********************************这里是回调的结束***********************************");
},
"用于回调的");
3.AsyncResult.IsCompleted可用于判断异步是否执行完成