2009-07-14 83 views
0

我有一个C#程序,它使用内置于SeralPort类中的 与串行设备进行通信。但是,我想要执行异步写入 并为此我使用BaseStream.BeginWrite()。在异步回调 我调用BaseStream.EndWrite()。所有这些工作正常。但是,有时 我想在BeginWrite()完成之前关闭一个端口,但只要BeginWrite()挂起,调用 Close()会导致它挂起。 我曾尝试调用EndWrite(),但如果BeginWrite() 处于挂起状态,那也会挂起。我如何杀死BeginWrite()线程?出现 是没有BaseStream.Abort()或类似的。使用BaseStream强制终止串行COM端口IO应用程序中的BeginWrite

感谢

回答

1

我找到了一个方法,但它有点hackish。该方法关闭端口并中止,但在该过程中抛出了一些例外情况。基本上,我使用反射来获取设备的文件句柄如下:

object p = _port.BaseStream.GetType().GetField("_handle", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField).GetValue(_port.BaseStream); 
IntPtr hFile = (IntPtr)p.GetType().GetField("handle", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField).GetValue(p); 

_port是打开的SerialPort。然后我关闭该文件如下

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
static extern bool CloseHandle(IntPtr hFile); 
CloseHandle(hFile); 

有可能是通过调用在BaseStream私有方法一个更好的方法,但这是一种方式:)


0

我也认为你无法取消操作,如果Stream.Close()不会做的伎俩。 EndWrite()在设计上,在同一线程上的BeginWrite()EndWrite()的序列与调用同步功能相同。

实际上,甚至可能没有线程在运行。该操作可能会在内部使用IO完成端口,并仅在线程池线程上触发回调。 (这是我查看过的东西以来的一段时间)

但是你可以做的是'放弃'流,在你的代码中设置一个标志,当回调到达时,如果标志被设置,关闭流。请记住在国旗附近放一个lock或让它volatile

+0

我放弃了流是罚款。但是,尝试重新打开会导致失败。我怀疑这可能无法完成。有趣的是,我有一个商业的win32控制台应用程序,它可以做同样的事情并且工作正常。 谢谢。 – HiteshP 2009-07-16 14:22:54