如何正确处理此代码
本文关键字:代码 正确处理 | 更新日期: 2023-09-27 18:34:48
我有一个相当大的项目,我尽量保持干净整洁。当我在Visual Studio中运行代码分析器时,我收到一个可靠性错误,我觉得这很烦人。我真的很想学习如何解决它。这是我正在做的事情的一个简化示例。
这是警告。
警告 1 CA2000:Microsoft.可靠性:在方法"MyExampleClassForStackOverflow.AddFeed(string("中,在对象"new FeedClassExamle(("上调用 System.IDisposable.Dispose 在对象 'new FeedClassExamle((' 上,然后所有对它的引用都超出范围。
这是我的示例代码:
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())
{
}
欢迎任何建议。
存在警告是因为代码分析工具无法确定对象是否会正确释放。 按照编写代码的方式,对象实际上不会正确释放,但修复代码可能不会消除警告。
从根本上说,需要发生的是针对每个AddFeed
方法,以确保某些东西将在它创建的每个FeedClassExample
实例上调用Dispose
。 最好的方法是避免创建FeedClassExample
实例(如果字典中已存在当前 ID 下的实例(。 如果做不到这一点,AddFeed
方法应该要么处理它创建的任何FeedClassExample
,但随后决定不存储在字典中,要么与字典中的那个交换(我不确定ConcurrentDictionary
支持什么方法来做到这一点(,然后Dispose
旧的。 基本要求是,在实际执行AddFeed
之外的任何时候,字典将包含所有已创建但未销毁的FeedClassExample
实例。
在 FeedClassExample
类中添加析构函数可能会提供任何信息,该析构函数除了记录消息外什么都不做。 如果正确调用该类的Dispose
,则析构函数将永远不会执行。 如果您无法调用Dispose
,它会。 因此,如果析构函数执行,你可以知道你做错了什么。
如果 TryAdd 失败,对象不会被释放,因此请尝试显式执行此操作:
public void AddFeed(string id)
{
FeedClassExample fce = new FeedClassExamle();
if (!Feeds.TryAdd(id, fce))
{
fce.Dispose();
}
Feeds[id].Start();
}
仅在需要添加实例时才创建实例:
if (!Feeds.ContainsKey(id)) {
Feeds.GetOrAdd(id, new FeedClassExamle());
}