如何正确处置物品?为什么代码分析不断改变主意?

发布于 2024-11-27 07:31:29 字数 1756 浏览 2 评论 0原文

我昨天加入了一个项目,我们决定将我们的两个项目合并为一个,并融合两个项目的功能(它们基本上吸收了我们)。

问题是,他们在某个地方发生了内存泄漏,他们要求我找到并杀死它。

我在 Visual Studio 中运行了代码分析,并提出了一长串警告,其中大部分我们可以忽略,我试图修复的问题是对象处置问题。我从来没有真正特别关注过一些事情,而且我惊讶地发现通过代码分析来确定某些内容是正确的并不容易。

代码是这样开始的:

StreamWriter SW = new StreamWriter(File.Create("folder/file.txt"));
SW.WriteLine("text");
SW.WriteLine("text");
SW.WriteLine("text");
SW.WriteLine();
SW.WriteLine("text");
SW.WriteLine("text");
SW.WriteLine("text");
SW.Close();
SW.Flush();

但是代码分析说 File.Create 并没有沿着所有代码路径被处理,并且 SW 可以被多次处理,我去寻找并发现你不应该同时使用 Close 和 Flush,事实上,你应该使用一个 using 语句,所以我将其更改为:

using(StreamWriter SW = new StreamWriter(File.Create("folder/file.txt")))
{
    SW.WriteLine("text");
    SW.WriteLine("text");
    SW.WriteLine("text");
    SW.WriteLine();
    SW.WriteLine("text");
    SW.WriteLine("text");
    SW.WriteLine("text");
}

正在处理的 SW 消失了,但它仍然说 File.Create 没有沿着所有代码路径被处理,只有一个代码路径,所以它没有意义,我尝试添加一个单独的Using File.Create 的语句,以及单独创建/写入文件,但代码分析仍然捕获它。

这似乎很容易弄清楚,除非 VS 出现误报或其他情况。

无论如何,感谢您给我时间阅读本文。

〜编辑

我在原来的帖子中撒了谎,当我添加双重使用语句时,包括当我使用“Stream”时,它告诉我该对象可以被多次处理,从而导致对象处置异常。我推测这可能是某种奇怪的现象。因为我自己从来不处理它。

当前代码:

using (Stream stream = File.Create("folder/file.txt"))
{
    using (StreamWriter SW = new StreamWriter(stream))
    {
        SW.WriteLine("");
        SW.WriteLine("");
        SW.WriteLine("");
        SW.WriteLine();
        SW.WriteLine("");
        SW.WriteLine("");
        SW.WriteLine("");
    }
}

这个有效并且VS通过了,非常感谢。

using (StreamWriter SW = File.CreateText("text/awardsList.txt"))
{
    SW.WriteLine("");
    SW.WriteLine("");
    SW.WriteLine("");
    SW.WriteLine();
}

I joined a project yesterday, we decided to merge our two projects into one, and incorporate the features of both (they basically absorbed us).

The problem is, they have a memory leak somewhere, and they tasked me with finding and killing it.

I ran a Code Analysis in Visual Studio and came up with a long list of Warnings, most of which we can ignore, the ones I'm trying to fix are problems with object disposing. Something i've never really payed special attention to, and I'm surprised to find out that getting code analysis to decide that something is correct is not easy.

The code Started as this:

StreamWriter SW = new StreamWriter(File.Create("folder/file.txt"));
SW.WriteLine("text");
SW.WriteLine("text");
SW.WriteLine("text");
SW.WriteLine();
SW.WriteLine("text");
SW.WriteLine("text");
SW.WriteLine("text");
SW.Close();
SW.Flush();

But Code Analysis said that File.Create wasn't disposed of along all code paths and that SW can be disposed of more then once, I went looking and discovered that your not supposed to use both Close and Flush, and in fact, you should use a using statement, so i changed it to this:

using(StreamWriter SW = new StreamWriter(File.Create("folder/file.txt")))
{
    SW.WriteLine("text");
    SW.WriteLine("text");
    SW.WriteLine("text");
    SW.WriteLine();
    SW.WriteLine("text");
    SW.WriteLine("text");
    SW.WriteLine("text");
}

The SW being disposed went away, but it still said that File.Create wasn't being disposed of along all code paths, there is only one code path, so It didn't make sense, I tried adding a separate Using statement for File.Create, and Creating/writing the file separately, but code analysis still catches it.

This seems like something that would be easy to figure out, unless VS has a false positive or something.

Anyway, thanks for giving me the time to read this.

~EDIT

I lied in the origional post, when i add the double using statement, including when I use "Stream" it tells me the object can be disposed of more then once, causing an objectdisposedexception. I'm presuming that it would be in some weird freak occurrence. since I never dispose of it myself.

current code:

using (Stream stream = File.Create("folder/file.txt"))
{
    using (StreamWriter SW = new StreamWriter(stream))
    {
        SW.WriteLine("");
        SW.WriteLine("");
        SW.WriteLine("");
        SW.WriteLine();
        SW.WriteLine("");
        SW.WriteLine("");
        SW.WriteLine("");
    }
}

This one worked AND VS Passed it, thank you very much.

using (StreamWriter SW = File.CreateText("text/awardsList.txt"))
{
    SW.WriteLine("");
    SW.WriteLine("");
    SW.WriteLine("");
    SW.WriteLine();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花伊自在美 2024-12-04 07:31:29

我怀疑它正在寻找这样的东西:

using (Stream stream = File.Create("folder/file.txt"))
{
    using (StreamWriter writer = new StreamWriter(stream))
    {
        ...
    }
}

假设如果 File.Create 成功,那么 StreamWriter 构造函数也会成功,这可能是合理的 - 但 VS 也可能不会知道这一点。它也可能不知道处理写入会处理流。

就我个人而言,我会使用 File.CreateText相反,这避免了这个问题并且更简单:)

using (TextWriter writer = File.CreateText("folder/file.txt"))
{
    ...
}

I suspect it's looking for something like this:

using (Stream stream = File.Create("folder/file.txt"))
{
    using (StreamWriter writer = new StreamWriter(stream))
    {
        ...
    }
}

It's probably reasonable to assume that if File.Create succeeds, then so will the StreamWriter constructor - but it's possible that VS doesn't know that. It may also not know that disposing of the write disposes of the stream.

Personally I'd use File.CreateText instead though, which avoids the issue and is simpler :)

using (TextWriter writer = File.CreateText("folder/file.txt"))
{
    ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文