当前位置: 首页 > 编程语言 > C#

如何终止挂起的APM操作分享

时间:2023-04-10 17:31:00 C#

如何终止挂起的APM操作如果有挂起的操作,比如stream.BeginRead(_buffer,0,_buffer.Length,_asyncCallbackRead,this);并关闭流提供者,例如serialPort.Close();不出所料,您会导致异常。在关闭端口之前,是否有一种首选方法可以取消挂起的APM操作?Colby的回答不是我所希望的答案,但他至少关闭了一条毫无结果的途径。很高兴我找到了解决方案。对于每个流,我在DeviceSession类中维护各种状态信息。此类有一个方法ReadStream,它为处理传入数据的AsyncCallback提供实现。请注意,_asyncCallbackRead和所有其他以下划线开头的变量都是在DeviceSession的构造函数中分配的类私有成员。构造函数还提供对_stream.BeginRead的初始调用。voidReadStream(IAsyncResultar){if(IsOpen)try{DevicePacket数据包;intcbRead=_stream.EndRead(ar);_endOfValidData+=cbRead;while((packet=GetPacket())!=null)CommandStrategy.Process(this,packet);_stream.BeginRead(_buffer,_endOfValidData,_buffer.Length-_endOfValidData,_asyncCallbackRead,null);}catch(Exceptionex){Trace.TraceError("{0}rn{1}",ex.Message,ex.StackTrace);_restart(_streamProvider,_deviceId);请注意,我没有设置ar.AsyncState。由于回调委托引用DeviceSession特定实例的方法,因此详细的强类型上下文信息(包含在此DeviceSession实例的成员中)将自动包含在范围内。这是拥有会话对象的关键。回到中止侦听器的主题,关闭流提供程序会触发回调,但尝试调用EndRead会导致IOException。通常,此类异常表示需要重新启动侦听器的故障,并且需要通过重新启动流提供程序和重新创建会话来响应。由于缺乏可靠的独立于流提供者的方式来确定提供者是否已关闭或用户是否正在尝试重新启动连接(例如,通过将新设备插入端口),这变得复杂。诀窍是向DeviceSession添加更多上下文(IsOpen)以指示会话是打开还是关闭,并使用它来顺利完成ReadStream的最终中止执行。如果IsOpen为真,则IOException指示恢复失败。如果IsOpen为false,则有意引发错误并且不需要任何操作。框架不直接支持这一点。最好的办法是编写一个包装器来生成线程并使用像事件这样的同步原语来发出取消请求信号。HTHColbyAfrica[受C#CLR中Richter的APM章节的启发,我决定看看SO在这个问题上有什么好处,我发现了这个问题。我认为Peter在这里提出了一个很好的问题并做了一些研究-这是结果]JeffreyRichter在CLRviaC#(第27章)中讨论了他的AsyncEnumerator类,它(据说)消除了很多痛苦。此类(他免费提供的PowerThreadingLibrary的一部分)的一个特性是能够取消异步操作。该课程可以从上面的链接下载。该页面还包含指向YahooGroupRichter的链接,该链接旨在为该库提供有限支持。他在这些MSDN文章中介绍了这个库:SimplifyingAPMwithAsyncEnumeratorMoreAsyncEnumeratorfunctionalityThat'sallforC#LearningTutorial:HowtoTerminatePendingAPMOperations教程,希望大家多多关注—本文收集自网络,确实不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: