UWP Unhandled Exception when writing to serial

0

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!

c#
uwp
serial-port
windows-10
ntdll
asked on Stack Overflow Jan 27, 2018 by Mateusz Sadowski • edited Jan 28, 2018 by marc_s

2 Answers

2

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.

answered on Stack Overflow Jan 30, 2018 by Mateusz Sadowski
1

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.

answered on Stack Overflow Jan 29, 2018 by Xie Steven

User contributions licensed under CC BY-SA 3.0