Proper way to prematurely abort BeginRead and BeginWrite?
Asked Answered
M

1

4

I have a utility I've written in C# to communicate back and forth with our USB device. We use the generic HID driver and wrap a handle to the device in a FileStream object. I read/write data using its BeginRead and BeginWrite methods, not because I need asynchronous IO, but simply so I can timeout in case the device enters a noncommunicable state (intentionally or not). All reading/writing is done in my own dedicated IO thread.

I'm worried that I'm not quite doing things properly, because I've seen a few cases of what I suspect is thread deadlock. Here is a stripped down version of my relevant Read method (which seems to work just fine).

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
}

My primary question is how to properly stop an unfinished BeginRead or BeginWrite call if I need to terminate my IO thread and my device is no longer communicating. I can't just call EndRead because it will sit there and block forever. Is it safe to call Filestream.Close while read/write operations are pending?

I also have to ask, is it safe to have pending read and write operations running simultaneously? For example, if my read method times out, can I still go ahead and try to write something?

It's hard to reproduce my current deadlock issue, but the really strange part is it seems to start when the IO thread gets "stuck" in my read method. I'm not sure how that would even happen unless my code isn't working the way I think it is.

Method answered 2/8, 2012 at 21:2 Comment(0)
C
6

There is no built-in cancellation. Closing the stream is the recommended solution. Just make sure you catch exceptions when you call EndRead...

If you want to use .NET 4.5, there is a new FileStream.ReadAsync that supports cancelation: http://msdn.microsoft.com/en-us/library/hh158566(v=vs.110)

Castellatus answered 2/8, 2012 at 21:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.