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

Handle Exception that happens within a using statement (IDisposable)

我正在使用 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 语句一起使用。 这个结论是否正确,或者有其他方法可以处理这种情况吗?

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() 调用。


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