【发布时间】:2020-01-22 12:21:41
【问题描述】:
我对 .NET C# 中的 ConcurrencyDictionary 有疑问。 我的应用程序将是异步的(我尝试这样做:))。
我有一些外部设备,它们通过一些 TCPIP 通信将数据发送到我的核心 (C# .NET)。我将对象存储在每个设备的 ConcurrentDictionary 值中。我对这些数据进行了一些操作,我需要在其中读取它并且有时会更改对象中的一些内容。
现在看起来不错,没有死锁(当我增加外部/模拟设备的数量时,它不会变慢,但它可以同时处理更多消息(并且不会丢失数据)
但是:我不确定我是否正确使用它。 我需要更改对象内部的一些值,调用一些函数并将所有更改存储在字典中。 dict 中的所有对象都必须可供其他进程读取(我知道在“DoJob”期间,其他进程可以在 dict 中有旧值,直到我保存值,但在我的情况下没关系)。我只需要避免阻塞/锁定其他任务并使其尽可能快。
哪种方式更好:
1路(我现在用):
var dict = new ConcurentDictionary<MyClass>(concurrencyLevel, initalCapacity);
private async Task DoJob(string myKey)
{
MyClass myClass;
MyClass myClassInitState;
dict.TryGetValue(myKey, out myClass);
dict.TryGetValue(myKey, out myClassInitState);
var value = myClass.SomeValueToRead;
myClass.Prop1 = 10;
await myClass.DoSomeAnotherJob();
dict.TryUpdate(myKey, myClass, myClassInitState);
}
2路:
var dict = new ConcurentDictionary<MyClass>(concurrencyLevel, initalCapacity);
private async Task DoJob(string myKey)
{
var value = dict[myKey].SomeValueToRead;
dict[myKey].ChangeProp1(10);
await dict[myKey].DoSomeAnotherJob();
}
第二种方式看起来更加清晰和简单。但是我不确定我是否可以因为异步而做到这一点。
我会阻塞其他线程/任务吗?
哪种方式会更快?我期待第一个,因为在 DoJob 内部我不使用 dict,而是使用一些对象副本,毕竟我会更新 dict。
直接读取值(#2)会减慢整个过程吗?
即使在#2 方式中,其他进程是否可以从 dict 读取最后实现的值而没有任何麻烦?
当我打电话时会发生什么:
dict[myKey].DoSomeAnotherJob();
它是等待的,所以它不应该阻塞线程。但实际上它是在共享字典中调用的。
【问题讨论】:
标签: c# .net multithreading dictionary asynchronous