过早中止BeginRead和BeginWrite的正确方法?

时间:2012-08-02 21:02:51

标签: c# .net windows io usb

我有一个用C#编写的实用程序来与我们的USB设备来回通信。我们使用通用HID驱动程序并将句柄包装到FileStream对象中的设备。我使用BeginReadBeginWrite方法读取/写入数据,不是因为我需要异步IO,而是因为我可以在设备进入非可通信状态(有意或无意)时超时。所有读/写都在我自己的专用IO线程中完成。

我担心我做得不好,因为我看到了一些我怀疑是线程死锁的情况。这是我的相关Read方法的精简版(似乎工作正常)。

if (_readResult == null)
{
  _readResult = _deviceStream.BeginRead(_readBuffer, 0, _readBuffer.Length, null, null);
}

if (_readResult.AsyncWaitHandle.WaitOne(IOTimeout, true))
{
  int bytesRead = _deviceStream.EndRead(_readResult);
  _readResult.AsyncWaitHandle.Close();
  _readResult= null;
  // … Copy bytes to another buffer
}
else
{
  // … Timeout, so retry again in a bit
}

我的主要问题是如果我需要终止我的IO线程并且我的设备不再通信,如何正确停止未完成的BeginReadBeginWrite调用。我不能只是打电话给EndRead,因为它会坐在那里永远阻止。在读/写操作挂起时调用Filestream.Close是否安全?

我还要问,同时运行挂起的读写操作是否安全?例如,如果我的读取方法超时,我还可以继续尝试写一些东西吗?

很难再现我当前的死锁问题,但真正奇怪的是它似乎是在IO线程在我的read方法中“卡住”时开始的。我不确定除非我的代码按照我认为的方式工作,否则甚至会发生这种情况。

1 个答案:

答案 0 :(得分:6)

没有内置取消。建议的解决方案是关闭流。只需确保在调用EndRead时捕获异常......

如果你想使用.NET 4.5,有一个新的FileStream.ReadAsync支持取消:http://msdn.microsoft.com/en-us/library/hh158566(v=vs.110