Max*_*ich 11 c# collections parallel-processing concurrency multithreading
我最近注意到,在System.Collections.Concurrent命名空间中包含的集合对象中,通常会看到Collection.TrySomeAction()而不是Collection.SomeAction().
这是什么原因?我认为它与锁定有关?
所以我想知道在什么条件下尝试(例如)从堆栈,队列,包等中取出项目..失败?
Nic*_*nko 10
System.Collections.Concurrent命名空间中的集合被认为是线程安全的,因此可以使用它们来编写在线程之间共享数据的多线程程序.
在.NET 4之前,如果多个线程可能正在访问单个共享集合,则必须提供自己的同步机制.每次修改元素时都必须锁定集合.每次访问(或枚举)它时,您也可能需要锁定集合.这是最简单的多线程场景.某些应用程序会创建后台线程,随着时间的推移将结果传递给共享集合.另一个线程将读取并处理这些结果.您需要在线程之间实现自己的消息传递方案,以便在新结果可用时以及消耗这些新结果时相互通知.类和接口System.Collections.Concurrent为那些以及其他常见的多线程编程问题提供了一致的实现,这些问题涉及以无锁方式跨线程共享数据.
Try<something>具有语义 - 尝试执行该操作并返回操作结果.DoThat语义通常使用异常抛出的机制来指示可能无效的错误.作为例子,他们可以返回false,
ConcurentDictionary;试着读:
失败是什么意思?
请看以下示例:
var queue = new Queue<string>();
string temp = queue.Dequeue();
// do something with temp
Run Code Online (Sandbox Code Playgroud)
上面的代码抛出异常,因为我们试图从空队列中出队.现在,如果你ConcurrentQueue<T>改用:
var queue = new ConcurrentQueue<string>();
string temp;
if (queue.TryDequeue(out temp))
{
// do something with temp
}
Run Code Online (Sandbox Code Playgroud)
上面的代码不会抛出异常.队列仍然无法使项目出列,但代码不会以抛出异常的方式失败.在多线程环境中,这一点的实际用途变得明显.非并发代码Queue<T>通常如下所示:
lock (queueLock)
{
if (queue.Count > 0)
{
string temp = queue.Dequeue();
// do something with temp
}
}
Run Code Online (Sandbox Code Playgroud)
为了避免竞争条件,我们需要使用一个锁来确保在检查Countdo调用时从队列中没有任何反应Dequeue.有了ConcurrentQueue<T>,我们真的不需要检查Count,但可以改为打电话TryDequeue.
如果检查中发现的类型Systems.Collections.Concurrent的命名空间,你会发现他们中许多人换两个操作通常被称为顺序,而传统上会需要锁定(Count其次是Dequeue在ConcurrentQueue<T>,GetOrAdd在ConcurrentDictionary<TKey, TValue>替代调用的顺序ContainsKey,增加一个项目,并得到它,并等等).
| 归档时间: |
|
| 查看次数: |
5285 次 |
| 最近记录: |