相关疑难解决方法(0)

当与ConcurrentDictionary <Tkey,TValue>一起使用时,C#LINQ OrderBy线程是否安全?

我的工作假设是,当与System.Collections.Concurrent集合(包括ConcurrentDictionary)一起使用时,LINQ是线程安全的.

(其他Overflow帖子似乎同意:链接)

但是,对LINQ OrderBy扩展方法的实现的检查表明,对于实现ICollection的并发集合的子集(例如ConcurrentDictionary),它似乎不是线程安全的.

所述OrderedEnumerable 的GetEnumerator(源此处)构造一个实例缓冲结构(源这里它试图收集强制转换为)的ICollection(其ConcurrentDictionary实现),然后用初始化为集合的大小的阵列执行collection.CopyTo.

因此,如果在OrderBy操作期间ConcurrentDictionary(在这种情况下为具体的ICollection)的大小增加,在初始化数组和复制到它之间,此操作将抛出.

以下测试代码显示此异常:

(注意:我很欣赏在一个线程安全的集合上执行一个OrderBy,这个集合在你下面发生变化并没有那么有意义,但我不相信它应该抛出)

using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Program
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                int loop = 0;
                while (true) //Run many loops until exception thrown
                {
                    Console.WriteLine($"Loop: {++loop}");

                    _DoConcurrentDictionaryWork().Wait();
                }
            }
            catch …
Run Code Online (Sandbox Code Playgroud)

.net c# linq concurrency

11
推荐指数
1
解决办法
760
查看次数

.NET ConcurrentDictionary.ToArray()ArgumentException

当我调用ConcurrentDictionary.ToArray时,有时我会收到以下错误.错误如下:

System.ArgumentException:索引等于或大于数组的长度,或者字典中的元素数大于从索引到目标数组末尾的可用空间.at System.Collections.Concurrent.ConcurrentDictionary 2.System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.CopyTo(KeyValuePair2 [] array,Int32 index)at System.Linq.Buffer 1..ctor(IEnumerable1 source)at System.Linq.Enumerable.ToArray [TSource](IEnumerable 1 source) at ...Cache.SlidingCache2.RemoveExcessAsync(Object state)in ...\SlidingCache.cs:System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)的第141行,位于System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx) System.Threading.ThreadPoolWorkQueue.Dispatch()中的.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()

我注意到在多线程场景中,有时在对ConcurrentDictionary进行排序时会出现异常.见堆栈溢出的问题在这里.所以我在排序之前开始使用ConcurrentDictionary.ToArray.在创建阵列时似乎仍然存在问题.

并发字典用于缓存,当达到缓存的设置的最大元素数时,该缓存维护对象并刷新最后访问的对象.多个线程访问缓存,并且在尝试删除旧元素时发生上述错误,因此可以将新元素添加到数组中.请参阅下面的一些代码段:

public class SlidingCache<TKey, TValue> : IDictionary<TKey, TValue>
{
    public int MinCount { get; private set; }
    public int MaxCount { get; private set; }
    private readonly IDictionary<TKey, CacheValue> _cache = new ConcurrentDictionary<TKey, CacheValue>();

    public SlidingCache(int minCount=75000, int maxCount=100000)
    {
        if (minCount <= 2)
            throw new ArgumentException("minCount"); …
Run Code Online (Sandbox Code Playgroud)

c# multithreading concurrentdictionary

10
推荐指数
1
解决办法
1229
查看次数