4

我有一个用 C# 编写的实用程序,用于与我们的 USB 设备来回通信。我们使用通用 HID 驱动程序并将设备句柄包装在一个FileStream对象中。BeginRead我使用它的and方法读/写数据BeginWrite,不是因为我需要异步 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 线程并且我的设备不再通信,如何正确停止未完成的BeginRead或调用。BeginWrite我不能只是打电话EndRead,因为它会坐在那里永远阻塞。Filestream.Close在读/写操作挂起时调用是否安全?

我还要问,同时运行挂起的读写操作是否安全?例如,如果我的 read 方法超时,我还能继续尝试写点什么吗?

很难重现我当前的死锁问题,但真正奇怪的是,当 IO 线程“卡”在我的读取方法中时,它似乎开始了。我不确定这会如何发生,除非我的代码没有按照我认为的方式工作。

4

1 回答 1

6

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

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

于 2012-08-02T21:09:42.887 回答