最近项目中需要用到异步编程,虽然以前研究过,但时间一长竟然就都忘了
于是就又再重新学习了一遍……
首先引用MSDN中的一段话来描述一下如何使用异步方式:
.NET Framework 允许您异步调用任何方法。 为此,应定义与您要调用的方法具有相同签名的委托;公共语言运行时会自动使用适当的签名为该委托定义 BeginInvoke 和 EndInvoke 方法。
BeginInvoke 方法启动异步调用。 该方法与您需要异步执行的方法具有相同的参数,还有另外两个可选参数。 第一个参数是一个 AsyncCallback 委托,该委托引用在异步调用完成时要调用的方法。 第二个参数是一个用户定义的对象,该对象将信息传递到回调方法。 BeginInvoke 立即返回,不等待异步调用完成。 BeginInvoke 返回一个 IAsyncResult,后者可用于监视异步调用的进度。
EndInvoke 方法检索异步调用的结果。 在调用 BeginInvoke 之后随时可以调用该方法。 如果异步调用尚未完成,则 EndInvoke 会一直阻止调用线程,直到异步调用完成。 EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数(在 Visual Basic 中为 <Out> ByRef 和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。
如果上面的介绍不明白,没有关系,下面我将通过一个简单的例子来进行演示。
先看一下程序主界面图,以便后面的代码说明较好理解:
从中可以看出,老黄可以同时烧开水和看电视,这就是异步。下面给出老黄类的定义:
public class LaoHuang
{
//定义委托
private delegate void BoilWaterDelegate();
//声明委托变量
BoilWaterDelegate boilwaterDelegate;
/// <summary>
/// 看电视
/// </summary>
public void WatchTV()
{
}
/// <summary>
/// 烧水
/// </summary>
public void BoilWater()
{
//模拟烧水的过程
Thread.Sleep(5000);
}
public IAsyncResult BeginBoilWater(Action call)
{
boilwaterDelegate = new BoilWaterDelegate(BoilWater);
IAsyncResult result = boilwaterDelegate.BeginInvoke(new AsyncCallback(CallBack), call);
return result;
}
public void EndBoilWater(IAsyncResult result)
{
boilwaterDelegate.EndInvoke(result);
}
/// <summary>
/// 回调函数
/// </summary>
private void CallBack(IAsyncResult result)
{
Action call = result.AsyncState as Action;
call();
}
}然后,给出界面中的代码:
private void button_Click(object sender, EventArgs e)
{
LaoHuang laohuang = new LaoHuang();
resultTextbox.AppendText(GetTime()+"老黄想喝茶了……\r\n");
laohuang.BeginBoilWater(ActionCallBack);
resultTextbox.AppendText(GetTime()+"老黄开始烧水……\r\n");
laohuang.WatchTV();
resultTextbox.AppendText(GetTime() + "老黄打开了电视……\r\n");
}
private void ActionCallBack()
{
//MethodInvoker 表示一个委托,该委托可执行托管代码中声明为 void 且不接受任何参数的任何方法
resultTextbox.Invoke((MethodInvoker)(() => {
resultTextbox.AppendText(GetTime() + "水烧开了,老黄泡好了茶……\r\n");
resultTextbox.AppendText(GetTime() + "老黄可以一边喝茶,一边看电视了……\r\n");
}));
}
private string GetTime()
{
return DateTime.Now.ToLongTimeString()+"->";
}
原文:http://blog.csdn.net/bobo1013767522/article/details/19773633