5

我最近与一位同事讨论过,他告诉我我正在错误地将流管理到 try/catch/block 中。所以我想知道什么对你来说是个好方法。

try
{
    StreamReader sr = new StreamReader("TestFile.txt");
    //After that, here an operation of about 30 seconds to fulfill;
}
catch (IOException ioex)
{
    throw new IOException("An error occurred while processing the file.", ioex);
}
catch (Exception ex)
{
    throw new Exception("An generic error ocurred.");
}
finally
{
    if(sr != null){
        stream.Close();
        stream = null;
    }
}

他说,即使使用 IOException,也不需要有 2 个异常。我们只能使用异常。但我唯一想要的是识别出异常究竟是在哪里产生的,因为打开文件后,将执行大约 30 秒的操作。

那么你会怎么想?我们看到了这个 MS 示例 ( http://msdn.microsoft.com/fr-Fr/library/system.io.streamreader.aspx ),它更简单,但就性能或干净的代码而言,你觉得有些奇怪吗?

请发表您的意见!

-编辑 - - - - - - - - -

好的,我明白了这一点,但我们正在讨论 Catch IOException 并且只是使用 Exception。在我看来,就像上面的例子一样,你可以知道错误发生在哪里;在管理文件的那一刻或打开文件后的过程中。这是我的第一个问题。现在,您如何看待下面的这种变化。

try
{
    using(StreamReader sr = new StreamReader("TestFile.txt"))
    {
        //After that, here an operation of about 30 seconds to fulfill;
    }
}
catch (Exception ex)
{
    throw new Exception("An generic error ocurred.");
}
finally
{
    if(sr != null){
        stream.Close();
        stream = null;
    }
}

-------------------编辑2------------

最后,我希望这将是我的最终解决方案。非常感谢您的回答。因此使用更快、更高效,并且只需要一个例外。

try
{
    using (StreamReader stream = sr = new StreamReader("TestFile.txt"))
    {
        //Operation
    }
}
catch (Exception e)
{
    throw new Exception(String.Format("An error ocurred while executing the data import: {0}", e.Message), e);
}

任何其他评论将不胜感激!

4

3 回答 3

13

您可以使用using如下块,即使发生异常,它也会处理流

using (StreamReader sr = new StreamReader("TestFile.txt"))
{
   // do something with sr
}

如果您要对此做点什么,请捕获异常。如果你不能解决问题,那么抓住它是没有意义的。

如果您无法解决异常,最好让异常冒泡异常并在那里捕获它。

try
{
    using(StreamReader sr = new StreamReader("TestFile.txt"))
    {
       // your code 
    }
}
catch (IOException ioex)
{
    // do something to fix the problem 
    // log the exception 
}
于 2013-10-31T02:36:16.707 回答
7

不要捕获异常只是为了立即抛出相同的异常,只是现在信息较少并且缺少实际发生异常的堆栈帧。

如果我遇到类似的东西

catch (Exception ex)
{
   throw new Exception("An generic error ocurred.");
}

在代码审查中,我会通过审查(不仅仅是语法和拼写错误;-)

至少,您应该将其与原始异常一起作为内部异常抛出。

catch (Exception ex)
{
    throw new Exception("A generic error occurred.", ex)
}

但坦率地说,在这个示例代码中它没有添加任何内容,最好将它完全删除。

于 2013-10-31T03:04:50.610 回答
4

如果您要重新抛出异常而不是捕获它,为什么还要创建一个新异常呢?您正在丢弃有价值的信息。捕获异常只是为了再次抛出它实际上是没有意义的。替换有用的异常也没有任何意义(例如,它具有上游任何人可能需要的所有诊断信息)并用通用异常替换它。

对于您的情况,我只想:

using(var sr=new StreamReader())
{
    //some code
}

你所有的其他改进都完全相反。

于 2013-10-31T03:03:28.950 回答