2

我有一个相当大的项目,我尽量保持干净整洁。当我在 Visual Studio 中运行代码分析器时,我得到一个我觉得很烦人的可靠性错误。我真的很想学习如何解决它。这是我正在做的一个简化示例。

这是警告。

警告 1 CA2000:Microsoft.Reliability:在方法“MyExampleClassForStackOverflow.AddFeed(string)”中,在对对象“new FeedClassExamle()”的所有引用超出范围之前调用 System.IDisposable.Dispose。

这是我的示例代码:

class MyExampleClassForStackOverflow : IDisposable
{
    public ConcurrentDictionary<string, FeedClassExamle> Feeds { get; set; }

    public void AddFeed(string id)
    {
        //The warning is coming from this code block.
        //In the full code, the feed classes collects data on a specific 
        //interval and feeds them back using events.
        //I have a bunch of them and they need to be accessible so I 
        //store them in dictionaries using keys to effeciently find them.
        Feeds.TryAdd(id, new FeedClassExamle());
        Feeds[id].Start();
    }
    public void Dispose()
    {
        foreach (var item in Feeds)
            item.Value.Dispose();
    }
}

class FeedClassExamle : IDisposable
{
    public void Start()
    {

    }
    public void Dispose()
    {

    }
}

为了测试代码,请使用:

using (var example = new MyExampleClassForStackOverflow())
{

}

任何建议都会受到欢迎。

4

3 回答 3

1

如果 TryAdd 失败,该对象不会被 Disposed,因此请尝试显式执行此操作:

public void AddFeed(string id)
{
    FeedClassExample fce = new FeedClassExamle();
    if (!Feeds.TryAdd(id, fce))
    {
        fce.Dispose();
    } 
    Feeds[id].Start();
}
于 2012-05-20T14:20:53.647 回答
1

存在警告是因为代码分析工具无法确定对象是否会被正确处理。根据您的代码编写方式,该对象实际上不会被正确处理,但修复代码可能不会消除警告。

从根本上说,需要为每个AddFeed方法确保某些东西会调用它创建Dispose的每个FeedClassExample实例。最好的方法是避免创建一个FeedClassExample实例,如果一个实例已经存在于当前 ID 下的字典中。如果做不到这一点,该AddFeed方法应该处理FeedClassExample它创建的任何内容,但随后决定不存储在字典中,或者与字典中的那个交换(我不确定哪些方法ConcurrentDictionary支持这样做),然后Dispose是旧的一。基本要求是,在实际执行之外的任何时候,字典都将保存所有已创建但未销毁AddFeed的实例。FeedClassExample

It may be informative to add a destructor in your FeedClassExample class which does nothing except log a message. If you are calling Dispose on that class correctly, the destructor will never execute. If you fail to call Dispose, it will. Thus, if the destructor ever executes, you can know you're doing something wrong.

于 2012-05-20T20:47:30.513 回答
0

仅在需要添加时才创建实例:

if (!Feeds.ContainsKey(id)) {
  Feeds.GetOrAdd(id, new FeedClassExamle());
}
于 2012-05-20T14:36:34.917 回答