Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 防止多次处置对象_C#_.net_Stream_Dispose_Msdn - Fatal编程技术网

C# 防止多次处置对象

C# 防止多次处置对象,c#,.net,stream,dispose,msdn,C#,.net,Stream,Dispose,Msdn,考虑以下代码: using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate)) { using (StreamWriter writer = new StreamWriter(stream)) { // Use the writer object... } } 当writer流被处理时,它在内部处理文件流流 除了在finally条款中处理外部使用的流之外,是否还有其他设计

考虑以下代码:

using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
{
    using (StreamWriter writer = new StreamWriter(stream))
    {
        // Use the writer object...
    }
}
writer
流被处理时,它在内部处理文件流

除了在finally条款中处理外部使用的流之外,是否还有其他设计:

Stream stream = null;
try
{
    stream = new FileStream("file.txt", FileMode.OpenOrCreate);
    using (StreamWriter writer = new StreamWriter(stream))
    {
        stream = null;
        // Use the writer object...
    }
}
finally
{
    if(stream != null)
        stream.Dispose();
}

这种特殊情况的解决方案是调用

不幸的是,这只适用于.NET4.5;否则你将不得不做你已经在做的事情

另外,请参见此线程:

顺便说一句,OP中的代码在我尝试时不会导致异常

以下示例假定存在名为“C:\TEST”的文件夹:


在这种情况下,FxCop与.NET Framework中的设计选择存在很大的分歧。问题是由StreamWriter假设流的所有权引起的。一般来说,这是一种“落入成功陷阱”的设计选择,大多数程序员会认为关闭StreamWriter就足以处理流。尤其是当他们使用Close()而不是Dispose()时

这在绝大多数情况下都很有效。在大多数情况下,CryptoStream是一种非常有问题的特殊用法。当底层流在加密流被刷新和释放之前关闭时,需要刷新和不可诊断的故障的类。在这种情况下,FxCop警告是合适的,尽管它太神秘,无法轻易识别特定问题;)

一般情况下,程序员编写了自己的Dispose()方法,却忘了确保它不会被多次调用。这正是FxCop警告想要引起注意的地方,否则它不够聪明,无法看到Dispose方法实际上是安全的

在这种特定情况下,FxCop警告毫无用处。所有.NET Framework提供的Dispose()方法实现都是安全的。FxCop应该自动抑制.NET framework代码的此类警告。但事实并非如此,微软也在使用它。在.NET framework源代码中有大量的[SuppressMessage]属性

处理警告太难看了,而且容易出错。而且毫无意义,因为实际上没有什么问题。请记住,FxCop只是一个诊断工具,旨在生成“您是否考虑过这个”消息。如果你无视规则,不是警察会把你关进监狱。这是编译器的工作


使用[SuppressMessage]属性关闭警告。

根据Microsoft的说法,您应该能够多次调用同一对象的Dispose()。@MatthewWatson,引用Microsoft on的引用会很好。@MatthewWatson当第1次使用时,尝试处理一个已准备就绪的对象,它会导致错误否,它不是试图处理一个已经被处理的对象,而是试图使用那个对象(通过关闭/刷新它)。@Miky:看,这说明如果一个对象的dispose方法被调用多次,那么该对象必须忽略第一次调用之后的所有调用。你为什么要谈论异常?这是一个代码分析警告。只是一个信息:在我的例子中,我刚刚注意到即使是.net 4.5也不会帮助我,因为我的例子中的“内部”流是XmlTextWriter,它没有leaveOpen标志!知道微软使用SuppressMessage来压制其警告真的很有趣。许多人将这些规则视为编程圣经。在我的例子中,使用stringwriter和textxmlwriter更为复杂,因此我必须将字符串保存在tempvariable中,然后才能按照msdn上的建议将stringwriter设置为null。
using System;
using System.IO;

namespace Demo
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            // This does NOT cause any exceptions:

            using (Stream stream = new FileStream("c:\\test\\file.txt", FileMode.OpenOrCreate))
            {
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    writer.Write("TEST");
                }
            }
        }
    }
}