应用框架的设计与实现——.NET平台(7.事件通知服务.委托.异步编程)
2006-12-31 23:18
1371 查看
7.2.1 委托
取得消息接收者列表 delesobj.GetInvocationList()
调用每个委托目标 deleobj.DynamicInvoke()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
Delegate[] delegates = allTargets.GetInvocationList();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
object[] params = ...{4,3};
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
foreach (Delegate dg in delegates)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
try
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
int result = (int)dg.DynamicInvoke(params);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Console.WriteLine("result is {0}", result);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
catch (Exception ex)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// ignore the exception
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
7.2.2 异步编程
异步调用委托 dele.BeginInvoke(p1, p2, p3, p4) // 后两个参数是回调方法相关的,前面是委托方法的参数
委托方法结果的信息 IAsynResult
委托是否执行结束 IAsynResult.IsCompleted
获取委托方法的结果 dele.EndInvoke(IAsynResult)
委托对象有个方法 BeginInvoke() 可以使委托对象以异步方式(新线程内)运行,该方法是编译时编译器为委托对象加入的。
委托对象运行在内部线程池中,内部线程池是什么?
每个应用程序域有一个线程池,默认包含25个线程。当通过 BeginInvoke() 调用委托时,CLR将使用这个线程池处理委托。
如果异步委托太多,超过了线程池中的空闲线程数,CLR会自动让委托排队,当有线程闲置时再处理它们。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
CalculationHandler slowAddHandler = new CalculationHandler(math.SlowAdd);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
// 异步方式调用方法
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
IAsynResult ar = slowAddHandler.BeginInvoke(4, 3, null, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
// 检查方法是否已经执行完
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
while (!ar.IsCompleted)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.Threading.Thread.Sleep(1000);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
// 取得方法执行结果
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
object slowResult = slowAddHandler.EndInvoke(ar);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
Console.Write("SlowAdd returns " + (int)slowResult);
如何使用异步调用方法的回调方法?如何使用 BeginInvoke() 方法的后两个参数?
1.BeginInvoke() 方法的倒数第二个参数是委托对象 AsyncCallback() 类型,
1.1当异步委托方法执行完后异步委托会执行回调函数,这样我们“不停的检查异步委托方法是否执行完”的问题也解决了。
1.2委托对象 AsyncCallback() 有一个参数是 IAsynResult 类型的,
1.3当异步委托执行回调函数时会以 BeginInvoke() 返回的 IAsynResult 对象为参数的,
2.同时 BeginInvoke() 的倒数第一个参数会以 IAsynResult.AsyncState 属性的形式出现。
AsyncCallback 委托的定义如下(类库内定义的):
public delegate void AsyncCallback(IAsyncResult asyncResult)
回调方法:
resultObject.AsyncDelegate 取得异步委托
result.AsyncState BeginInvoke()的最后一个参数
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
public void OnSlowAddComplete(IAsyncResult result)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
AsyncResult resultObject = (AsyncResult)result;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// 取得委托对象
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
CalculationHandler completedDelegate = (CalculationHandler)resultObject.AsyncDelegate;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// 取得返回值
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
int sum = (int)completedDelegate.EndInvoke(result);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Console.WriteLine("the result is " + sum);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Console.WriteLine("the last parameter is " + result.AsyncState.ToString());
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
执行异步委托方法时使用回调方法:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
AsyncCallback callback = new AsyncCallback(this.OnSlowAddComplete);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
IAsynResult ar = slowAddHandler.BeginInvoke(4, 3, callback, "last 参数");
当应用的流程需要多个方法都有结果才能继续时,我们必须等每个方法都执行结束。
如何等每个方法都执行结束?
WaitHandle[] 异步委托等待句柄数组
ar1.AsyncWaitHandle
WaitHandle.WaitAll() 阻塞当前线程,直到所有异步委托方法执行完
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
IAsynResult ar1 = slowAdd.BeginInvoke(5, 2, null, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
IAsynResult ar2 = sub.BeginInvoke(3, 3, null, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
IAsynResult ar3 = multiply.BeginInvoke(4, 13, null, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
WaitHandle[] waitArray = ...{ar1.AsyncWaitHandle, ar2.AsyncWaitHandle, ar3.AsyncWaitHandle};
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
WaitHandle.WaitAll(waitArray);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
int result1 = slowAdd.EndInvoke(ar1);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
int result2 = sub.EndInvoke(ar2);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
int result3 = multiply.EndInvoke(ar3);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
Console.Write(result1 + result2 + result3);
异常:
我们不知道异步委托什么时候发生异常,也不能即时处理它。
如果有异常发生了,我们怎么捕获它哪?
如果有异常会在调用 EndInvoke() 方法时抛出
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
IAsynResult ar1 = slowAdd.BeginInvoke(5, 2, null, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
WaitHandle.WaitAll(new WaitHandle[]...{ar1});
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
try
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
int result1 = slowAdd.EndInvoke(ar1);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
catch (Exception ex)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Console.Write(ex.Message);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
取得消息接收者列表 delesobj.GetInvocationList()
调用每个委托目标 deleobj.DynamicInvoke()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
Delegate[] delegates = allTargets.GetInvocationList();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
object[] params = ...{4,3};
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
foreach (Delegate dg in delegates)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
try
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
int result = (int)dg.DynamicInvoke(params);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Console.WriteLine("result is {0}", result);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
catch (Exception ex)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// ignore the exception
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
7.2.2 异步编程
异步调用委托 dele.BeginInvoke(p1, p2, p3, p4) // 后两个参数是回调方法相关的,前面是委托方法的参数
委托方法结果的信息 IAsynResult
委托是否执行结束 IAsynResult.IsCompleted
获取委托方法的结果 dele.EndInvoke(IAsynResult)
委托对象有个方法 BeginInvoke() 可以使委托对象以异步方式(新线程内)运行,该方法是编译时编译器为委托对象加入的。
委托对象运行在内部线程池中,内部线程池是什么?
每个应用程序域有一个线程池,默认包含25个线程。当通过 BeginInvoke() 调用委托时,CLR将使用这个线程池处理委托。
如果异步委托太多,超过了线程池中的空闲线程数,CLR会自动让委托排队,当有线程闲置时再处理它们。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
CalculationHandler slowAddHandler = new CalculationHandler(math.SlowAdd);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
// 异步方式调用方法
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
IAsynResult ar = slowAddHandler.BeginInvoke(4, 3, null, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
// 检查方法是否已经执行完
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
while (!ar.IsCompleted)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.Threading.Thread.Sleep(1000);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
// 取得方法执行结果
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
object slowResult = slowAddHandler.EndInvoke(ar);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
Console.Write("SlowAdd returns " + (int)slowResult);
如何使用异步调用方法的回调方法?如何使用 BeginInvoke() 方法的后两个参数?
1.BeginInvoke() 方法的倒数第二个参数是委托对象 AsyncCallback() 类型,
1.1当异步委托方法执行完后异步委托会执行回调函数,这样我们“不停的检查异步委托方法是否执行完”的问题也解决了。
1.2委托对象 AsyncCallback() 有一个参数是 IAsynResult 类型的,
1.3当异步委托执行回调函数时会以 BeginInvoke() 返回的 IAsynResult 对象为参数的,
2.同时 BeginInvoke() 的倒数第一个参数会以 IAsynResult.AsyncState 属性的形式出现。
AsyncCallback 委托的定义如下(类库内定义的):
public delegate void AsyncCallback(IAsyncResult asyncResult)
回调方法:
resultObject.AsyncDelegate 取得异步委托
result.AsyncState BeginInvoke()的最后一个参数
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
public void OnSlowAddComplete(IAsyncResult result)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
AsyncResult resultObject = (AsyncResult)result;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// 取得委托对象
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
CalculationHandler completedDelegate = (CalculationHandler)resultObject.AsyncDelegate;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// 取得返回值
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
int sum = (int)completedDelegate.EndInvoke(result);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Console.WriteLine("the result is " + sum);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Console.WriteLine("the last parameter is " + result.AsyncState.ToString());
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
执行异步委托方法时使用回调方法:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
AsyncCallback callback = new AsyncCallback(this.OnSlowAddComplete);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
IAsynResult ar = slowAddHandler.BeginInvoke(4, 3, callback, "last 参数");
当应用的流程需要多个方法都有结果才能继续时,我们必须等每个方法都执行结束。
如何等每个方法都执行结束?
WaitHandle[] 异步委托等待句柄数组
ar1.AsyncWaitHandle
WaitHandle.WaitAll() 阻塞当前线程,直到所有异步委托方法执行完
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
IAsynResult ar1 = slowAdd.BeginInvoke(5, 2, null, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
IAsynResult ar2 = sub.BeginInvoke(3, 3, null, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
IAsynResult ar3 = multiply.BeginInvoke(4, 13, null, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
WaitHandle[] waitArray = ...{ar1.AsyncWaitHandle, ar2.AsyncWaitHandle, ar3.AsyncWaitHandle};
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
WaitHandle.WaitAll(waitArray);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
int result1 = slowAdd.EndInvoke(ar1);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
int result2 = sub.EndInvoke(ar2);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
int result3 = multiply.EndInvoke(ar3);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
Console.Write(result1 + result2 + result3);
异常:
我们不知道异步委托什么时候发生异常,也不能即时处理它。
如果有异常发生了,我们怎么捕获它哪?
如果有异常会在调用 EndInvoke() 方法时抛出
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
IAsynResult ar1 = slowAdd.BeginInvoke(5, 2, null, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
WaitHandle.WaitAll(new WaitHandle[]...{ar1});
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
try
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
int result1 = slowAdd.EndInvoke(ar1);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
catch (Exception ex)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Console.Write(ex.Message);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
相关文章推荐
- 应用框架的设计与实现——.NET平台(7.事件通知服务.源码分析)
- 应用框架的设计与实现——.NET平台(8.1 Windows服务.线程)
- 应用框架的设计与实现——.NET平台(10 授权服务.PrincipalPermissionAttribute)
- 应用框架的设计与实现——.NET平台(10 授权服务.CodeAccessSecurityAttribute)
- 应用框架的设计与实现——.NET平台(5 缓存服务.源码分析)
- 应用框架的设计与实现——.NET平台(10 授权服务.源码分析)
- 应用框架的设计与实现——.NET平台(9 消息队列服务代码分析)
- 应用框架的设计与实现——.NET平台(9 MSMQ / MQSeries 访问)
- 应用框架的设计与实现——.NET平台(8.2 Windows服务)
- 应用框架的设计与实现——.NET平台(6 源码分析)
- 应用框架的设计与实现——.NET平台(4.3 SAF代码分析)
- 应用框架的设计与实现——.NET平台(6 自定配置文件节读取类)
- 应用框架的设计与实现——.NET平台(4.2 Remoting 无配置文件)
- 应用框架的设计与实现——.NET平台4.2代码测试问题解决
- 应用框架的设计与实现——.NET平台(8.3 调用非托管代码的方法)
- 应用框架的设计与实现——.NET平台(9 消息队列产品安装)
- 应用框架的设计与实现——.NET平台(4.2 Remoting 客户端激活)
- 应用框架的设计与实现——.NET平台(2)
- 应用框架的设计与实现——.NET平台(4)
- 应用框架的设计与实现——.NET平台(6.获取外部配置信息)