【问题标题】:Catch exception appropriate when disposing of the result?在处理结果时捕获适当的异常?
【发布时间】:2016-05-04 22:52:30
【问题描述】:

考虑以下代码:

public static Stream OpenWavStream(string path)
{
    var stream = new FileStream(path, FileMode.Open);

    try
    {
        stream.Seek(44, SeekOrigin.Current);
    }
    catch (Exception)
    {
        stream.Dispose();
        throw;
    }

    return stream;
}

我正在打开一个 wav 流,其数据始终从偏移量 44 开始。如果查找该偏移量失败,则释放该流,否则将其返回。考虑到catch (Exception) is considered bad practice,在这种情况下是否合适?

应该研究具体的异常(即使在 Stream.Seek 调用中发生任何类型的异常时应该处理流)还是将其移至 finally 块?

【问题讨论】:

  • 在此再次阅读 msdn 文档 .. 它解释了如何不捕获一般异常

标签: c# exception try-catch


【解决方案1】:

仅当流加载失败时。我用的东西:

string fileName = "C:\\PCM.wav";

if (!System.IO.File.Exists(fileName))
{
LogStatus("Wave file not found.");
return;
}
else
{
WaveFileByteArray = File.ReadAllBytes(fileName);
LogStatus("Wave file Loaded!" + Environment.NewLine);
}

这很好用。

然后玩/使用:

System.Media.SoundPlayer soundPlayer;
soundPlayer.Stream.Seek(0, SeekOrigin.Begin);
soundPlayer.Stream.Write(WaveFileByteArray, 0, WaveFileByteArray.Length);
soundPlayer.Play();

依赖异常来捕获可能的错误,如所介绍的,不是最佳实践,除非错误是意外的。最好的做法是在可能的错误发生之前处理它们。

【讨论】:

  • 您好,感谢您的回复。我无法将文件读入内存,因为在打开文件流时 wav 文件尚未完成。此外,我也不能延迟它,因为只有在写出这些位时才需要 wav 数据。感谢 SoundPlayer 代码,但我不需要它 :)
  • 你不能调用:"stream.Seek(44, SeekOrigin.Current);"如果没有 44 可以打电话。你需要重新考虑你的策略。也许多个 Wav 文件?没有提供足够的信息。
【解决方案2】:

catch (Exception) 如果您使用它来吞下异常而不处理它们,那么这是不好的做法。您将立即重新抛出异常,并正确执行(例如,您没有执行throw ex;)。您需要为 any 异常处理流,因此您不应在此处捕获特定异常。

您的代码非常好。但是,我对该方法的实用性持怀疑态度。在没有看到应用程序的其余部分的情况下,被调用者在 using 块内创建流可能是有意义的,即使使用辅助方法也是如此。

//In your callee code
using (var stream = new FileStream(path, FileMode.Open))
{
    ConfigureStream(steam);
    //Other stuff..
}

public static void ConfigureStream(Stream stream)
{
    stream.Seek(44, SeekOrigin.Current);
}

或者,您可以先检查流的长度,以完全避免异常。

【讨论】:

  • 感谢您回答我的问题!如果可以的话,我更喜欢使用,但我不能,因为在打开文件时 wav 文件还没有完成,所以很遗憾这不是一个选项。我担心的异常是 IOException、SecurityException、UnauthorizedAccessException。支持在流的末尾之外搜索,所以我认为不会有任何问题。
  • 我不确定你的意思.. 你应该仍然可以使用using。它所做的只是将您的代码包装在 try {} finally {} 块中,以便为您处理处置。在任何情况下,您总是需要在异常上处理流,因此需要catch (Exception)
【解决方案3】:

为什么不在调用方法中使用 using 块,并将 steam 的关闭留给系统。即使出现异常, using 也会关闭流。

public static Stream OpenWavStream(string path)
    {
        var stream = new FileStream(path, FileMode.Open);
        stream.Seek(44, SeekOrigin.Current);
        return stream;
    }

public static void UseWaveStream()
    {
        try
        {
            using(Stream thisStream = OpenWavStream("C:\\myfile.txt"))
            {
                 // do whatever 
            }
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }

【讨论】:

  • 不能使用using语句,因为打开后会写入数据到wav流。我无法将文件读入内存,因为在打开文件流时 wav 文件尚未完成。此外,我也不能延迟它,因为只有在写出这些位时才需要 wav 数据。
猜你喜欢
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 2017-11-25
  • 2019-05-03
  • 2014-03-21
  • 2012-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多