减少C#中的重复错误处理代码?

Wed*_*dge 38 c# error-handling exception

我对异常处理的工作方式从来没有完全满意,有很多异常和try/catch带来的表(堆栈展开等),但它似乎在这个过程中打破了很多OO模型.

无论如何,这是问题所在:

假设您有一些包装或包含网络文件IO操作的类(例如,在某个特定的UNC路径上读取和写入某个文件).由于各种原因,您不希望这些IO操作失败,因此如果您检测到它们失败,则重试它们并继续重试它们,直到它们成功或达到超时.我已经有了一个方便的RetryTimer类,我可以实例化它并用于在重试之间休眠当前线程并确定超时时间已经过去等等.

问题是你在这个类的几个方法中有一堆IO操作,你需要将它们包装在try-catch/retry逻辑中.

这是一个示例代码段:

RetryTimer fileIORetryTimer = new RetryTimer(TimeSpan.FromHours(10));
bool success = false;
while (!success)
{
    try
    {
        // do some file IO which may succeed or fail
        success = true;
    }
    catch (IOException e)
    {
        if (fileIORetryTimer.HasExceededRetryTimeout)
        {
            throw e;
        }
        fileIORetryTimer.SleepUntilNextRetry();
    }
}
Run Code Online (Sandbox Code Playgroud)

那么,如何避免在整个班级中为每个文件IO操作复制大部分代码?我的解决方案是在类中使用匿名委托块和单个方法来执行传递给它的委托块.这允许我在其他方法中做这样的事情:

this.RetryFileIO( delegate()
    {
        // some code block
    } );
Run Code Online (Sandbox Code Playgroud)

我有点喜欢这个,但它还有很多不足之处.我想听听其他人如何解决这类问题.

Mik*_*llo 14

这看起来是一个了解面向方面编程的绝佳机会.这是一篇关于.NET中AOP的好文章.一般的想法是,您将跨职能问题(即重试x小时)提取到一个单独的类中,然后您将注释需要以这种方式修改其行为的任何方法.这是它的外观(在Int32上有一个很好的扩展方法)

[RetryFor( 10.Hours() )]
public void DeleteArchive()
{
  //.. code to just delete the archive
}
Run Code Online (Sandbox Code Playgroud)