I have a task that is running continuously reading from a serial port. I don't see any outward reason that this wouldn't work, but I don't discount that I could be missing something obvious.
if (serialPort != null)
{
while (true)
{
Windows.Storage.Streams.Buffer inputBuffer = new Windows.Storage.Streams.Buffer(1024);
Windows.Storage.Streams.Buffer resultBuffer = new Windows.Storage.Streams.Buffer(1024);
using (var childCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(ReadCancellationTokenSource.Token))
{
var t = serialPort.InputStream.ReadAsync(inputBuffer, inputBuffer.Capacity, InputStreamOptions.Partial).AsTask(ReadCancellationTokenSource.Token);
resultBuffer = (Windows.Storage.Streams.Buffer)await t;
if (resultBuffer.Length > 0)
{
LogDebug(string.Format("Read {0} bytes", resultBuffer.Length));
DataReader dataReader = Windows.Storage.Streams.DataReader.FromBuffer(resultBuffer);
string resultString = dataReader.ReadString(resultBuffer.Length);
OnDataReceived(new DataReceiptEventArgs { Data = resultString });
}
}
await Task.Delay(10);
}
}
The result from this is that it reads correctly on the first iteration, but ReadAsync
does not seem to handle no data on the stream gracefully when the next iteration happens and all the data has already been read. I would like the behavior to be that task did not return until data was available. At the very least, I would expect an exception, so I might be able to catch that the read failed.
Instead, the debugger logs a message that my app 'has exited with code -1073741811 (0xc000000d).' which is STATUS_INVALID_PARAMETER
.
What am I doing wrong? Or will this really never work?
This code produces the same error:
if (serialPort != null)
{
dataReaderObject = new DataReader(serialPort.InputStream);
LogDebug("Listening...");
while (true)
{
uint ReadBufferLength = 1024;
ReadCancellationTokenSource.Token.ThrowIfCancellationRequested();
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
using (var childCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(ReadCancellationTokenSource.Token))
{
UInt32 bytesRead = 0;
bytesRead = await dataReaderObject.LoadAsync(ReadBufferLength).AsTask(childCancellationTokenSource.Token);
if (bytesRead > 0)
{
LogDebug(string.Format("Read {0} bytes", bytesRead));
string resultString = dataReaderObject.ReadString(bytesRead);
OnDataReceived(new DataReceiptEventArgs { Data = resultString });
}
}
await Task.Delay(10);
}
}
I think I figured it out.
As well as having a read thread going, I also was writing using a DataWriter
. But my write method would dispose of the DataWriter
on every write. Instead, I now have that declared as a private member of my serial class, and I instantiate the DataWriter
upon connection and dispose of it in my close method.
This seems to keep communication going.
Not sure why this happens though, any explanations are welcome.
User contributions licensed under CC BY-SA 3.0