如何正确处理此代码?

时间:2012-05-20 14:08:08

标签: c# dispose idisposable

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

这是警告。

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

这是我的示例代码:

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())
{

}

欢迎任何建议。

3 个答案:

答案 0 :(得分:1)

如果TryAdd失败,对象不会被废弃,所以请尝试明确地执行此操作:

public void AddFeed(string id)
{
    FeedClassExample fce = new FeedClassExamle();
    if (!Feeds.TryAdd(id, fce))
    {
        fce.Dispose();
    } 
    Feeds[id].Start();
}

答案 1 :(得分:1)

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

从根本上说,每个AddFeed方法都需要确保某些内容会在其创建的每个Dispose实例上调用FeedClassExample。最好的方法是避免在当前ID下的dictonary中存在FeedClassExample实例时创建AddFeed实例。如果失败了,FeedClassExample方法应该处理它创建的任何ConcurrentDictionary但是然后决定不存储在字典中,或者交换字典中的那个(我不知道是什么)方法Dispose支持这样做)然后AddFeed旧方法。基本要求是在FeedClassExample的实际执行之外的所有时间,字典将保存已创建但未被销毁的FeedClassExample的所有实例。

Dispose类中添加析构函数可能会提供信息,除了记录消息之外什么都不做。如果正确地在该类上调用Dispose,则析构函数将永远不会执行。如果你没有拨打{{1}},它就会。因此,如果析构函数执行,你就会知道你做错了什么。

答案 2 :(得分:0)

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

if (!Feeds.ContainsKey(id)) {
  Feeds.GetOrAdd(id, new FeedClassExamle());
}