处理在using语句中发生的异常(IDisposable)

时间:2016-06-22 17:37:17

标签: c# windows-runtime uwp datareader

我正在使用DataWriter and DataReader接口。 这些类实现了IDisposable接口,因此我将它们包装在using关键字:

周围
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();
}

这个帖子here说如果异常(这里是"TaskCancelledException"在using语句中发生,那么对象就会被释放。现在,问题在于UWP - DataReaderDataWriter:如果对象被处理,他们将关闭底层流。为了防止我调用datareader.DetachStream()然后处置。

当我们稍后需要底层的InputStream / Outputstream时,我们不能将DataReader / DataWriter与using语句一起使用。 这个结论是正确的还是有其他方法来处理这种情况?

1 个答案:

答案 0 :(得分:1)

using的全部含义是确保无论发生什么事情都将对象放置在块的末尾,而不必自己编写所有代码。这是通过将对象置于finally块内来完成的。

您要做的是在对象被处理之前调用datareader.DetachStream() - 再次无论发生什么

所以我的结论是using语句在这里不是很有用,你应该自己做,也许是这样:

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();
}

所以这基本上是using语句对您的代码的作用,除了您可以插入datareader?.DetachStream()调用。

注意即使没有datareader声明,using最终也会被处理掉。当保留此变量的范围时,垃圾收集可以随时决定从内存中删除此实例,这将导致调用其Dispose方法。因此,在离开范围之前需要调用DetachStream()