正确的方法来更新不断更新/读取的字典?

时间:2015-08-22 23:01:32

标签: c# dictionary updates

我有一个返回Dictionary<uint, SomeClass>的函数,每隔一次更新数据就会调用此函数到我的列表中。

现在,像这样用来更新我的财产:

MyData = Api.GetData();

我的财产为:

public static Dictionary<uint, SomeClass> MyData { get; private set; }
  • 这种方法可以更新我的词典或应该怎么做?

我的意思是,字典经常被替换,就像现在一样,对吗?因此,如果我正在使用或更新该词典的任何条目,请说:

MyData[SomeValidKey].SomeProperty

我的引用会变为空或无效?或者它会简单地使用它的副本?或者根据MyData被查询的速度等等,这只会有机会发生?

更新字典的最佳方法是什么,同时允许我的应用程序的其他部分自由访问和使用它?

字典主要是只读和/或调用字典中给定项目的函数,它是SomeClass的一部分。

更新

由于MyData = Api.GetData();表示列表实际被替换了?如果是这样,如果以前存在的条目不再存在但我的任何函数仍然使用它,它会导致异常吗?如果先前使用的项目已更新,我将没有更新的数据,因为我的引用已经死了?

所以我更新词典的方式显然是错误的?

2 个答案:

答案 0 :(得分:3)

如果您要在单独的帖子中更新Dictionary,那么您应该使用正确的锁定机制来确保您正在读取当前值。使用lock进行读/写操作。 .NET 4(或更高版本)中还有一个ConcurrentDictionary类,用于并发操作。 但如果您在一个帖子中使用字典,那么您根本不应该担心锁定问题。下面是一个示例,演示当您更改对另一个someClass实例的引用时会发生什么:

private class SomeClass
{
    public string Name { get; set; }
}
...
Dictionary<uint, SomeClass> dic = new Dictionary<uint, SomeClass>
{ 
  { 1u, new SomeClass { Name = "1"}},
  { 2u, new SomeClass { Name = "2"}}
};
var sc1 = dic[1]; // sc1 refers to old instance of SomeClass
dic[1] = new SomeClass { Name = "new" }; // now we change the reference here
string oldName = sc1.Name; // oldName is still "1", because sc1 points to the old instance

答案 1 :(得分:0)

您的问题与您的示例有所不同。您的示例表明您在调用API时正在替换字典。您的问题与更新相对应。

如果您要更新字典,则可以将Api调用的返回分配给临时字典,然后在MyData中传输/添加/删除值或将MyData传递给Api函数并在那里处理该功能。如果从应用程序的其他部分访问,这将使您的引用保持完整。

如果这是不可能的,那么当您用Api调用替换MyData对象时,您无法保证不会出现代码其他部分的错误。这里最简单的解决方案是不缓存MyData条目值,而是缓存其密钥。然后,您的应用程序的其他部分可以检查其缓存密钥是否有效并采取适当的措施。