标签: concurrentdictionary

ConcurrentDictionary 和 Clear() 函数。使值导出线程安全而不会丢失数据

在将值导出到列表 ex 的情况下以及在清除该字典之后使 ConcurrentDictionary 线程安全的任何想法。这样任何其他线程都无法在导出和清除之间添加数据。

像这样: ”

List<data> list;
list = (List<data>)_changedItems.Values; //get values before clearing
_changedItems.Clear();
Run Code Online (Sandbox Code Playgroud)

" 并且添加是由其他线程使用函数 _changedItems.AddOrUpdate 完成的

现在,如果某个线程在清除行之前将数据对象添加到集合中,则在从字典中获取数据和清除内容之间可能会丢失新数据。

或者是添加和清除内部锁的唯一方法。

lock(object)
{
    List<data> list;
    list = (List<data>)_changedItems.Values;  
    _changedItems.Clear();
}
Run Code Online (Sandbox Code Playgroud)

lock(object)
    _changedItems.AddOrUpdate
Run Code Online (Sandbox Code Playgroud)

需要一个清除函数来安全地从字典中返回所有已清除的项目。

-拉里

c# multithreading dictionary thread-safety concurrentdictionary

5
推荐指数
1
解决办法
5287
查看次数

AddOrUpdate时锁定ConcurrentDictionary?

我使用a ConcurrentDictioanry<string, HashSet<string>>来访问许多线程中的一些数据.

我在本文中读到(向下滚动)该方法AddOrUpdate未在锁中执行,因此可能危及线程安全.

我的代码如下:

//keys and bar are not the concern here
ConcurrentDictioanry<string, HashSet<string>> foo = new ...;
foreach(var key in keys) {
    foo.AddOrUpdate(key, new HashSet<string> { bar }, (key, val) => {
        val.Add(bar);
        return val;
    });
}
Run Code Online (Sandbox Code Playgroud)

为了确保一切都是线程安全的,我应该将声明括AddOrUpdatelock声明中吗?

.net c# thread-safety concurrentdictionary

5
推荐指数
1
解决办法
4961
查看次数

以异步方式在并发字典中调用valuefactory

我是C#ConcurrentDictionary类的新手,我想知道如何GetOrAdd以异步方式在方法中使用valueFactory .

public class Class1
{
    public int X = 10;

    public Class1(int x)
    {
        X = x;
        Debug.WriteLine("Class1 Created");
    }
}
Run Code Online (Sandbox Code Playgroud)

在WinForm按钮中测试代码逻辑:

private async void button1_Click(object sender, EventArgs e)
{
    var asyncDict = new ConcurrentDictionary<int, Task<Class1>>();

    Func<int, Task<Class1>> valueFactoryAsync = async (k) => new Class1(await Task.Run(async () =>
    {
        await Task.Delay(2000);
        Debug.WriteLine("Async Factory Called");
        return 5;
    }));

    var temp = await(asyncDict.GetOrAdd(1, valueFactoryAsync)).ConfigureAwait(false);
    Debug.WriteLine(temp.X);
    temp.X = 20;
    var temp2 = await (asyncDict.GetOrAdd(1, valueFactoryAsync)).ConfigureAwait(false);
    Debug.WriteLine(temp2.X);
}
Run Code Online (Sandbox Code Playgroud)

当第二次调用GetOrAdd方法时,它从并发字典返回一个Task.然后我在任务上调用await, …

c# asynchronous concurrentdictionary

5
推荐指数
1
解决办法
2415
查看次数

在来自 UWP 应用的 PCL 中使用 ConcurrentDictionary

我最近遇到了一个问题,想解释一下原因:

在使用Profile5 (.Net 4, Windows 8)的便携式类库 (PCL) 中,我有以下代码:

using System.Collections.Concurrent;

public class Foo
{
    public static void Bar(ConcurrentDictionary<string, bool> dict)
    {
        dict.AddOrUpdate("true", true, (k, v) => true);
    }

    public static void Baz()
    {
        new ConcurrentDictionary<string, bool>();
    }
}
Run Code Online (Sandbox Code Playgroud)

Bar在 Windows 10 UWP 应用程序中使用,如下所示:

var dict = new ConcurrentDictionary<string, bool>();
Foo.Bar(dict);
Run Code Online (Sandbox Code Playgroud)

它编译但崩溃:

找不到方法:'Void Foo.Bar(System.Collections.Concurrent.ConcurrentDictionary`2)'。

对 Baz 的调用以不同的方式失败:

尝试通过方法 'Foo.Baz()' 访问方法 'System.Collections.Concurrent.ConcurrentDictionary`2..ctor()' 失败。

所以看起来TypeForwardedTo魔法在这种情况下不起作用,或者消失了。编译器理解它应该是相同的类型(即使存在于不同的程序集中)但运行时没有。

在运行时使用反射,我可以看到确实有ConcurrentDictionary两种类型:

  • System.Collections.Concurrent.ConcurrentDictionary'2[[TKey, TValue]], System.Collections.Concurrent, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 当我使用 typeof(ConcurrentDictionary<,>)
  • System.Collections.Concurrent.ConcurrentDictionary'2[[TKey, TValue]], …

.net c# portable-class-library concurrentdictionary uwp

5
推荐指数
0
解决办法
370
查看次数

C# Dictionary 并发添加或修改仅针对不同的键,ConcurrentDictionary 有必要吗?

我有一个字典只支持addmodify操作并且可以并发操作,但总是针对不同的键。键是 int,值是引用类型。修改还意味着更改值的某些属性。

我的问题是:

  1. 在这种情况下我需要使用 ConcurrentDictionary 吗?如果需要的话,它有什么帮助?
  2. 如果可以对同一个键进行并发修改,ConcurrentDictionary 是否有助于确保线程安全?我的理解是否定的,这样正确吗?

谢谢!

.net c# concurrency dictionary concurrentdictionary

5
推荐指数
1
解决办法
3503
查看次数

可以递归调用ConcurrentDictionary.GetOrAdd()吗?

ConcurrentDictionary.GetOrAdd(TKey,Func <TKey,TValue>)接受一个工厂函数,允许将项目的延迟实例化放入字典中.

定义一个自己调用GetOrAdd()的工厂函数是安全的,即在'父'GetOrAdd()的上下文中调用GetOrAdd.

以下代码演示了该模式; 它确实有效,但它安全吗?

class Program
{
    static ConcurrentDictionary<string,object> __dict = new ConcurrentDictionary<string, object>();

    static void Main(string[] args)
    {
        Foo foo = GetOrAddFoo();
        Console.WriteLine(foo._name);
        Console.WriteLine(foo._bar._name);
        Console.ReadKey();
    }

    static Bar GetOrAddBar()
    {
        Console.WriteLine("GetOrAddBar: enter");
        Func<string,Bar> factoryFn = (x) => LoadBar(x);
        Bar bar = __dict.GetOrAdd("bar", factoryFn) as Bar;
        Console.WriteLine("GetOrAddBar: exit");
        return bar;
    }

    static Foo GetOrAddFoo()
    {
        Console.WriteLine("GetOrAddFoo: enter");
        Func<string,Foo> factoryFn = (x) => LoadFoo(x);
        Foo foo = __dict.GetOrAdd("foo", factoryFn) as Foo;
        Console.WriteLine("GetOrAddFoo: exit");
        return foo;
    }

    static Bar LoadBar(string …
Run Code Online (Sandbox Code Playgroud)

.net concurrentdictionary

5
推荐指数
1
解决办法
67
查看次数

为什么 ConcurrentDictionary 有 AddOrUpdate 和 GetOrAdd,而 Dictionary 没有?

在 .NET Framework 中,有DictionaryConcurrentDictionary. 这些提供诸如Add,Remove等方法...

我知道当我们设计一个多线程程序时,我们使用ConcurrentDictionary来代替Dictionary线程安全。

我不知道为什么ConcurrentDictionaryAddOrUpdateGetOrAdd和类似的方法,同时Dictionary也没有。

我们总是喜欢下面的代码从 a 获取对象Dictionary

var dict = new Dictionary<string, object>();
object tmp;
if (dict.ContainsKey("key"))
{
       tmp = dict["key"];
}
else
{
       dict["key"] = new object();
       tmp = new object();
}
Run Code Online (Sandbox Code Playgroud)

但是在使用时ConcurrentDictionary,类似的代码只有一行。

var conDict = new ConcurrentDictionary<string, object>();
var tmp = conDict.GetOrAdd("key", new object());
Run Code Online (Sandbox Code Playgroud)

我希望 .NET 有这些方法,但为什么没有呢?

.net c# dictionary concurrentdictionary

5
推荐指数
1
解决办法
539
查看次数

根据类的当前实现,通过直接枚举 ConcurrentDictionary 将 ConcurrentDictionary 复制到普通 Dictionary 是否安全?

TL;DR: a 的单个枚举是否可以ConcurrentDictionary两次发出相同的键?该类的当前实现(.NET 5)是否ConcurrentDictionary允许这种可能性?


我有一个ConcurrentDictionary<string, decimal>由多个线程同时变异的 ,我想定期将其复制到普通Dictionary<string, decimal>,并将其传递到表示层以更新 UI 。有两种复制它的方法,带快照语义和不带快照语义:

var concurrent = new ConcurrentDictionary<string, decimal>();

var copy1 = new Dictionary<string, decimal>(concurrent.ToArray()); // Snapshot

var copy2 = new Dictionary<string, decimal>(concurrent); // On-the-go
Run Code Online (Sandbox Code Playgroud)

我非常确定第一种方法是安全的,因为该ToArray方法返回以下内容的一致视图ConcurrentDictionary

返回一个新数组,其中包含从 复制的键和值对的快照ConcurrentDictionary<TKey,TValue>

但我更喜欢使用第二种方法,因为它产生的争用较少。我担心获得的可能性ArgumentException: An item with the same key has already been added.文档似乎并没有排除这种可能性:

从字典返回的枚举器...并不代表字典的即时快照。通过枚举器暴露的内容可能包含GetEnumerator调用后对字典所做的修改。

这是让我担心的情况:

  1. 线程 A 开始枚举ConcurrentDictionary,并且键X由枚举器发出。然后该线程被操作系统暂时挂起。
  2. 线程 B 移除钥匙 …

c# multithreading dictionary concurrentdictionary

5
推荐指数
1
解决办法
1999
查看次数

这个 ConcurrentDictionary + Lazy&lt;Task&lt;T&gt;&gt; 代码是如何工作的?

各种 帖子/答案表示,如果键尚不存在,则ConcurrentDictionary GetOrAdd当使用委托计算要插入字典中的值时,.NET/.NET Core 的方法不是线程安全的。Func

我相信,当使用 aConcurrentDictionary的方法的工厂方法时GetOrAdd,如果“同时”发生多个请求,则可以“同时/快速连续地”多次调用它。这可能会造成浪费,尤其是当呼叫“昂贵”时。(@panagiotis-kanavos 比我解释得更好)。有了这个假设,我正在努力理解我制作的一些示例代码似乎是如何工作的。

我已经在 .NET Fiddle 上创建了一个工作示例,但我一直试图理解它是如何工作的。

普通的推荐我读过的建议/想法是Lazy<Task<T>>ConcurrentDictionary. 这个想法是阻止Lazy其他调用执行底层方法。

完成繁重工作的代码的主要部分是这样的:

    public static async Task<DateTime> GetDateFromCache()
    {
        var result = await _cache.GetOrAdd("someDateTime", new Lazy<Task<DateTime>>(async () => 
        {
            // NOTE: i've made this method take 2 seconds to run, each time it's called.
            var someData = await GetDataFromSomeExternalDependency();
            
            return DateTime.UtcNow;
            
        })).Value;
        
        return result;
    }
Run Code Online (Sandbox Code Playgroud)

我是这样读的:

  • 检查 …

.net c# asynchronous concurrentdictionary

5
推荐指数
1
解决办法
896
查看次数

.NET 并发字典交换值

是否有类似于ConcurrentDictionary<TKey,TValue>和的数据结构Interlocked.Exchange<T>(...),它允许您自动设置新值并检索分配给任意键的旧值?任何超载似乎都不可能AddOrUpdate(...)

.net c# collections concurrency concurrentdictionary

5
推荐指数
1
解决办法
98
查看次数