COM 经验的八个教训(7):使用线程或异步调用来避免 DCOM 超时设定太长
来源:互联网 发布:flotherm软件破解 编辑:程序博客网 时间:2024/04/30 17:04
使用线程或异步调用来避免 DCOM 超时设定太长
总是有人问我当 DCOM 无法完成远程实例化请求或方法调用时出现的超时设定太长的问题。典型的场景如下:客户端调用 CoCreateInstanceEx 来实例化远程机器上的一个对象,但是这台机器临时离线了。在 Windows NT 4.0 上,激活请求不会立即失败,DCOM 可能会花上一分钟或更长时间来返回失败的 HRESULT。DCOM 还可能花费很长时间,使指向已不再存在或其主机已离线的远程对象的方法调用失败。如果可能,开发人员应该如何避免这些较长的超时设定呢?
要回答这个问题,几句话是讲不清楚的。DCOM 高度依赖于基础网络协议和 RPC 子系统。并没有什么神奇的设置可让您限制 DCOM 超时设定的持续时间。但是,我经常使用两种技巧来避免较长超时设定的负作用。
在 Windows 2000 中,当调用在 COM 信道中挂起时,您可以使用异步方法调用来释放调用线程。(有关异步方法调用的介绍,请参 MSDN Magazine 2000 年 4 月刊的“Windows 2000: Asynchronous Method Calls Eliminate the Wait for COM Clients and Servers Alike”。如果异步调用在合理时间内没有返回,您可以通过调用用于初始化调用的调用对象上的 ICancelMethodCalls::Cancel 来取消它。
Windows NT 4.0 不支持异步方法调用,甚至在 Windows 2000 中也不支持异步激活请求。怎么解决呢?从背景线程调用远程对象(或是实例化该对象的请求)。使主线程在事件对象上阻塞,并指定超时设定值以反映您愿意等待的时间长度。当调用返回时,让背景线程来设置事件。假设主线程使用 WaitForSingleObject 阻塞,当 WaitForSingleObject 返回时,返回值可以告诉您,返回是因为方法调用或激活请求返回,还是因为您在 WaitForSingleObject 调用中指定的超时设定到期。您不能在 Windows NT 4.0 中取消挂起调用,但是至少主线程可以自由地执行自己的任务。
图 5中的代码演示了基于 Windows NT 4.0 的客户端如何才能从背景线程调用对象。在此示例中,线程 A 封送了一个 IFoo 接口指针,并启动线程 B。线程 B 取消封送了该接口指针,并调用 IFoo::Bar。无论调用返回所花费的时间有多长,线程 A 都不会阻塞超过 5 秒钟,因为它在 WaitForSingleObject 的第二个参数中传递的是 5,000 (单位为微秒)。这并不是太好的办法,但是如果“无论在线路的另一端发生什么情况,线程 A 都不会挂起”这一点很重要的话,忍受这种麻烦也算值得。
- COM 经验的八个教训(7):使用线程或异步调用来避免 DCOM 超时设定太长
- COM 经验的八个教训(6):DCOM 不适于防火墙
- COM 经验的八个教训
- COM 经验的八个教训
- COM 经验的八个教训(1):总是调用 CoInitialize(Ex)
- (转载)来自 COM 经验的八个教训
- 来自 COM 经验的八个教训
- 来自 COM 经验的八个教训
- 来自 COM 经验的八个教训
- 来自 COM 经验的八个教训(转)
- 来自 COM 经验的八个教训
- 来自 COM 经验的八个教训
- 来自 COM 经验的八个教训
- COM 经验的八个教训(2):不要在线程之间传递原始接口指针
- COM 经验的八个教训(3):STA 线程需要消息循环
- 超酷代码:来自 COM 经验的八个教训
- 超酷代码:来自 COM 经验的八个教训
- 超酷代码:来自 COM 经验的八个教训
- Web应用导出Excel报表的简单实现(HTML)
- DataGrid列操作
- COM 经验的八个教训(6):DCOM 不适于防火墙
- Linux编译内核的详细配置
- 嵌入式Linux入门的误区
- COM 经验的八个教训(7):使用线程或异步调用来避免 DCOM 超时设定太长
- 解决ASP.NET创建的线程的用户改变引发的"拒绝访问"错误
- FEEL之旅
- 使用Repeater的Template
- 嵌入式Linux发展现状
- 十年MFC经历认识的Microsoft技术[收藏]
- 提高JBuilder开发WEB层的效率
- 利用反射从 XML 构造 VO
- COM 经验的八个教训(8):共享对象并不容易