如何使用try / catch / finally C#高效地管理Stream

时间:2013-10-31 02:30:52

标签: c# exception exception-handling stream try-catch

我最近与一位同事讨论过,他告诉我,我正在不经意地将一个流管理成一个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个Exception。我们只能使用Exception。但我唯一想要的是识别产生异常的位置,因为在打开文件后,将执行大约30秒的操作。

那你觉得怎么样?我们看到了这个MS示例(http://msdn.microsoft.com/fr-Fr/library/system.io.streamreader.aspx)哪个更简单但是在性能或干净的代码方面,你发现了一些奇怪的东西?

您的意见!

-edit -----------------

好的,我看到了这一点,但我们正在讨论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);
            }

如果有任何其他评论,将不胜感激!

3 个答案:

答案 0 :(得分:11)

您可以使用using阻止,如下所示,即使发生异常也会处理该流

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

Catch Exception如果你要做点什么的话。如果你无法解决问题,就没有必要抓住它。

如果你无法解决异常,最好让异常冒泡出异常并将其捕获。

try
{
    using(StreamReader sr = new StreamReader("TestFile.txt"))
    {
       // your code 
    }
}
catch (IOException ioex)
{
    // do something to fix the problem 
    // log the exception 
}

答案 1 :(得分:7)

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

如果我遇到类似

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

在代码审查中,我将无法审核(不仅仅是语法和拼写错误; - )

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

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

但坦率地说,在这个示例代码中它没有添加任何东西,它会更好地完全删除。

答案 2 :(得分:3)

如果您重新抛出异常而不是捕获异常,为什么还要创建新的异常呢?你丢掉了有价值的信息。捕获异常只是为了再次抛出它几乎没有意义。也没有任何一点取代一个有用的例外(例如,它有上游可能需要的所有诊断信息)并用一般例外替换它。

根据您的情况,我只是:

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

所有其他改进恰恰相反。