我有一个非常大的项目,我尽量保持干净整洁。当我在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())
{
}
欢迎任何建议。
答案 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());
}