相关疑难解决方法(0)

你应该实现IDisposable.Dispose(),以便它永远不会抛出?

对于C++(析构函数)中的等效机制,建议通常不应抛出任何异常.这主要是因为这样做可能会终止您的流程,这很少是一个好策略.

在.NET的等效场景中......

  1. 抛出第一个异常
  2. 作为第一个异常的结果,执行finally块
  3. finally块调用Dispose()方法
  4. Dispose()方法抛出第二个异常

...您的流程不会立即终止.但是,由于.NET无法用第二个异常替换第一个异常,因此会丢失信息.因此,调用堆栈上某处的catch块将永远不会出现第一个异常.然而,人们通常对第一个例外更感兴趣,因为这通常会提供更好的线索,说明为什么事情开始出错.

由于.NET缺少一种机制来检测代码是否在异常处于挂起状态时被执行,因此似乎只有两种选择可以实现IDisposable:

  • 始终吞下Dispose()中发生的所有异常.不好,因为你可能最终吞下OutOfMemoryException,ExecutionEngineException等等,我通常宁愿在它们发生时拆除它而没有另外的异常已经挂起.
  • 让所有异常传播出Dispose().不好,因为您可能会丢失有关问题根本原因的信息,请参阅上文.

那么,两个邪恶中哪一个较小?有没有更好的办法?

编辑:为了澄清,我不是在谈论积极抛出Dispose()或不抛出异常,我说的是让Dispose()调用的方法抛出的异常传播出Dispose()或不传播,例如:

using System;
using System.Net.Sockets;

public sealed class NntpClient : IDisposable
{
    private TcpClient tcpClient;

    public NntpClient(string hostname, int port)
    {
        this.tcpClient = new TcpClient(hostname, port);
    }

    public void Dispose()
    {
        // Should we implement like this or leave away the try-catch?
        try
        {
            this.tcpClient.Close(); // Let's assume that this might throw
        }
        catch
        {
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

.net c# idisposable

54
推荐指数
3
解决办法
5845
查看次数

处理C#中嵌套的"using"语句

我注意到using我的代码中嵌套语句的级别最近有所增加.究其原因,可能是因为我使用越来越多的async/await格局,这往往增加了至少一个以上usingCancellationTokenSourceCancellationTokenRegistration.

那么,如何减少嵌套using,所以代码看起来不像圣诞树?之前已经提出了类似的问题,我想总结一下我从答案中学到的东西.

使用邻近using而不缩进.一个假的例子:

using (var a = new FileStream())
using (var b = new MemoryStream())
using (var c = new CancellationTokenSource())
{
    // ... 
}
Run Code Online (Sandbox Code Playgroud)

这可能有用,但通常会有一些代码using(例如,创建另一个对象可能为时过早):

// ... 
using (var a = new FileStream())
{
    // ... 
    using (var b = new MemoryStream())
    {
        // ... 
        using (var c = new CancellationTokenSource())
        {
            // ... 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

将相同类型(或强制转换IDisposable)的对象组合成单个对象using,例如:

// …
Run Code Online (Sandbox Code Playgroud)

c#

30
推荐指数
3
解决办法
9896
查看次数

"async void"WPF命令处理程序中的异常处理

我正在审查我的同事的一些WPF代码,这是一个基于组件的,UserControl包含许多async void事件和命令处理程序.这些方法目前不在内部实现任何错误处理.

代码简而言之:

<Window.CommandBindings>
    <CommandBinding
        Command="ApplicationCommands.New"
        Executed="NewCommand_Executed"/>
</Window.CommandBindings>
Run Code Online (Sandbox Code Playgroud)
private async void NewCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
    // do some fake async work (and may throw if timeout < -1)
    var timeout = new Random(Environment.TickCount).Next(-100, 100);
    await Task.Delay(timeout);
}
Run Code Online (Sandbox Code Playgroud)

抛出异常但未在内部观察到的异常NewCommand_Executed 只能在全局级别上处理(例如,使用AppDomain.CurrentDomain.UnhandledException).显然,这不是一个好主意.

我可以在本地处理异常:

private async void NewCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
    try
    {
        // do some fake async work (throws if timeout < -1)
        var timeout = new …
Run Code Online (Sandbox Code Playgroud)

.net c# wpf error-handling async-await

10
推荐指数
1
解决办法
1938
查看次数

标签 统计

c# ×3

.net ×2

async-await ×1

error-handling ×1

idisposable ×1

wpf ×1