I'm having an issue with writing to a serial device in UWP. My task for writing to the port looks like this:
public async Task WriteAsync(byte[] stream)
{
if (stream.Length > 0 && serialDevice != null)
{
await writeSemaphore.WaitAsync();
try
{
DataWriter dataWriter = new DataWriter(serialDevice.OutputStream);
dataWriter.WriteBytes(stream);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
dataWriter = null;
}
finally
{
writeSemaphore.Release();
}
}
}
The code works fine the first two times I call this function. The third time I get Unhandled Exception in ntdll.dll in the await dataWriter.StoreAsync() line.
The full exception I can see is:
Unhandled exception at 0x00007FFCB3FCB2C0 (ntdll.dll) in xx.exe: 0xC000000D: An invalid parameter was passed to a service or function.
This answer mentions a garbage collector closing an input stream, however I don't see why would it happen in my code. Any help on getting to the bottom of this issue would be highly appreciated!
Turns out the solution to my problem was in another piece of code. I had a function reading the bytes like this:
private async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 1024;
// If task cancellation was requested, comply
cancellationToken.ThrowIfCancellationRequested();
// Set InputStreamOptions to complete the asynchronous read operation when one or more bytes is available
dataReader.InputStreamOptions = InputStreamOptions.Partial;
using (var childCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
{
// Create a task object to wait for data on the serialPort.InputStream
loadAsyncTask = dataReader.LoadAsync(ReadBufferLength).AsTask(childCancellationTokenSource.Token);
// Launch the task and wait
UInt32 bytesRead = await loadAsyncTask;
if (bytesRead > 0)
{
byte[] vals = new byte[3]; //TODO:adjust size
dataReader.ReadBytes(vals);
//status.Text = "bytes read successfully!";
}
}
}
Specifically the problem was in the following two lines:
byte[] vals = new byte[3]; //TODO:adjust size
dataReader.ReadBytes(vals);
As soon as I set the size of the vals array to bytesRead value the problem went away.
Normally, you would not have to set dataWriter
to null, because the GC will know that an object will not be used anymore.
You'd better call dataWriter.Dispose()
method like many UWP samples.
For example: SocketActivityStreamSocket
Please read IDisposable.Dispose Method () document for more details.
User contributions licensed under CC BY-SA 3.0