WPF ConcurrentDictionary或SortedDictionary用于存储多个异步任务的结果

时间:2016-04-08 03:01:57

标签: c# wpf async-await concurrentdictionary sorteddictionary

以下示例代码段实现了async多任务处理功能,即:在线读取股票价格列表(特别是对应道琼斯工业平均指数)并将其异步存储在3个{{1} {{1} }:

Collection.Generics

Dictionary<string,double>

SortedDictionary<string,double>

该应用程序已经过测试,所有3个Generics似乎都能正常运行,而且到目前为止没有出现任何并发(竞赛条件)问题。

我的问题:即使快速测试产生了所有积极的结果,在这种类型的{{1}中使用ConcurrentDictionary<string,double>Dictionary<string,double>是否安全?多任务WPF实现,还是需要使用SortedDictionary<string,double>以避免可能的并发/竞争条件问题?

重要:为了更加清晰,请注意此问题特定于async/await多任务实施(不仅仅是一般的TPL内容)。例如,在ConcurrentDictionary<string,double>实现中,完全可以直接访问任何UI控件(例如async/await)而不会出现并发/竞争问题的风险。我假设同样的考虑因素也适用于Windows类变量(特别是任何Generics数据结构,如本示例中使用的字典),使得以相同的方式使用它们是安全的,而无需额外的线程同步/ interlocking(即使常规的Collections / Dictionary本身不是线程安全的,但await可能会处理同步问题)。

清单1.通过多个TextBox任务

在线阅读股票报价的示例应用程序
await

3 个答案:

答案 0 :(得分:2)

除了只读访问权限之外,

DictionarySortedDictionary不是线程安全的。如果任何一个实例可以被任何线程与另一个使用它的线程同时修改,那么你必须同步。否则,你不需要。

在您的示例中,await的每次使用都在UI线程的上下文中,因此await之后的延续(即每个await之后出现的代码)将继续使用也出现在UI线程中。这意味着每个集合实例仅在UI线程中使用,因此修改和访问必然不会同时发生。它们通过使用await来序列化,以在单个线程中执行延续代码。

答案 1 :(得分:0)

如果同时使用,我肯定会使用ConcurrentDictionary。你可以无数次地测试并获得积极的结果,然后在100或1000次中它会做一些不可预测的事情。 通常的工作实际上是一个问题,因为当它不存在时,你将无法重现错误。

几天前

Here's a thread。我做了一个并发操作的简单示例,有时我可以运行它一百次而没有任何问题。情景略有不同(它涉及序列。)但潜在的概念仍然是相同的。我处理大部分时间运行的生产应用程序,然后因为类似的问题而每隔一周锁定或行为不端。

答案 2 :(得分:0)

来自MSDN

  

字典可以同时支持多个读者,   只要集合没有被修改。即便如此,列举   通过集合本质上 是线程安全的   程序。在极少数情况下,枚举与写入竞争   访问时,必须在整个枚举期间锁定集合。    要允许多个线程访问集合以进行读写,您必须实现自己的同步。

ConcurrentDictionary<TKey,TValue>是通用Dictionary<TKey, TValue>集合的线程安全副本,两者都是为O(1)设计的 - 基于密钥查找数据。

在genral中,当我们需要一个concurrent字典时,我们正在交错读取和更新。它实现了thread-safety,没有共同锁定来提高效率。它实际上使用一系列锁来提供并发更新,并且具有lockless个读取。

最后但并非最不重要的,SortedDictionaryIDictionary的已排序实现,它们存储为有序树。虽然这些并不像未排序的词典那么快 - 它们是O(log2 n)速度和排序的组合。