【问题标题】:Forcing termination of BeginWrite in a Serial COM port IO app using BaseStream使用 BaseStream 在串行 COM 端口 IO 应用程序中强制终止 BeginWrite
【发布时间】:2009-07-24 02:17:30
【问题描述】:

我有一个 C# 程序,它使用 内置 SeralPort 类。但是,我想做异步写入 为此,我正在使用 BaseStream.BeginWrite()。在异步回调中 我调用 BaseStream.EndWrite()。这一切都很好。然而,有时 我想在 BeginWrite() 完成但调用之前关闭一个端口 只要 BeginWrite() 处于挂起状态,Close() 就会使其挂起。 我曾尝试调用 EndWrite() 但如果 BeginWrite() 也会挂起 等待中。如何杀死 BeginWrite() 线程?似乎有 不是 BaseStream.Abort() 或类似的。

谢谢

【问题讨论】:

    标签: c# serial-port


    【解决方案1】:

    我找到了一种方法,但它有点骇人听闻。此方法关闭端口并中止,但在此过程中引发了一些异常。基本上,我使用反射来获取设备的文件句柄如下:

    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 中的私有方法之一可能有更好的方法,但这是一种方法 :)


    【讨论】:

      【解决方案2】:

      我还认为,如果Stream.Close() 不成功,您将无法取消操作。 EndWrite() 在设计上阻塞,BeginWrite()EndWrite() 在同一线程上的序列与调用同步函数相同。

      实际上,您的操作可能甚至没有线程正在运行。该操作可能在内部使用 IO 完成端口,并且仅在线程池线程上触发回调。 (我已经有一段时间没有研究那些东西了)

      但是您可以做的是“放弃”流,在代码中设置一个标志,当回调到达时,如果设置了标志,只需关闭流。记得在旗帜周围加上lock 或设为volatile

      【讨论】:

      • 我放弃了直播,这很好。但是,尝试重新打开会导致失败。我怀疑它可能无法完成。有趣的是,我有一个商业 win32 控制台应用程序,它做同样的事情并且工作正常。谢谢。
      • 您是否尝试过一次性写入更少的数据?然后你可以更快地关闭。
      猜你喜欢
      • 2011-01-10
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多