I'm using the DataWriter and DataReader interfaces.
These classes have the IDisposable interface implemented, therefore I wrap them around the using
keyword:
using(var datareader = new DataReader(SerialPortInputStream))
{
CancellationTokenSource cancellation = new CancellationTokenSource();
//Timeout
cancellation.CancelAfter(1000);
//...
datareader.LoadAsync(120).AsTask(cancellation.Token);
//Some fancy methods
...
//Last step: Detach the InputStream to use it again
datareader.DetachStream();
}
This thread here is saying that if an Exception (here a "TaskCancelledException"
happens inside a using statement, the object gets disposed. Now, the problem is with the UWP-DataReader
and DataWriter
: They will close the underlying stream if the object gets disposed. To prevent that I've to call datareader.DetachStream() and then dispose.
We cannot use the DataReader/DataWriter with a using
statement when we need the underlying InputStream/Outputstream later again.
Is this conclusion correct or are there other ways to handle this situation?
The whole meaning of using
is to make sure that the object gets disposed at the end of the block no matter what happens without having to write all the code for this by yourself. This is done by disposing the object inside a finally
block.
What you are trying to do is to call datareader.DetachStream()
before the object gets disposed - again no matter what happens.
So my conclusion would be that the using
statement isn't very helpful here and you should do this by yourself, maybe like this:
DataReader datareader = null;
try
{
datareader = new DataReader(SerialPortInputStream);
CancellationTokenSource cancellation = new CancellationTokenSource();
//Timeout
cancellation.CancelAfter(1000);
//...
datareader.LoadAsync(120).AsTask(cancellation.Token);
//Some fancy methods
...
}
finally
{
//Last step: Detach the InputStream to use it again
datareader?.DetachStream();
datareader?.Dispose();
}
So this is essentially what the using
statement does to your code, except that you can insert the datareader?.DetachStream()
call.
Note that the datareader
would eventually get disposed anyway even without the using
statement. When the scope of this variable is left, the garbage collection may anytime decide to remove this instance from memory which would lead to a call to its Dispose
method. So a call to DetachStream()
is needed before leaving the scope.