首页 新闻 会员 周边 捐助

多线程的ConcurrentDictionary,两个线程一个访问、一个清空后填充

0
[已解决问题] 解决于 2020-05-28 11:03

背景:上游给出图像检测的结果,屏幕上的像素位置,我结合信息放在ConcurrentDictionary中,每次这个检测结果都是有变化的,没有好的办法去更新,只能清空重新赋值。。。

两个线程:
线程A:先清空这个ConcurrentDictionary,然后给里面写数据(两个操作在一个方法里)

//定义
public static ConcurrentDictionary<string,Point> info = new ConcurrentDictionary<string,Point>();
public static void funcA(){
info.Clear();

.........


info.tryAdd(string,point);
}

线程B遍历这个ConcurrentDictionary

public static void funB(){
foreach(var key in className.info.Keys){

    string theKey=key;//就是这里会抛出空指针异常,说什么 未将对象设置到引用的实例什么的
    Point p=className.info[k];

......................................
}

}
< >
分享
最佳答案
0

没有好的办法取更新是什么情况,ConcurrentDictionary不是有好几个更新方法么
而且,为什么要清空?直接创建一个新的ConcurrentDictionary替换掉之前那个不行么
还有,这个为什么要用两个线程

奖励园豆:5
拓拓 | 小虾三级 |园豆:1055 | 2020-05-28 10:10

图像识别,结果不稳定,一会有一会没有,位置也不稳定。没有规律去更新。
不能直接替换掉吧,因为这个是个公共变量,好多地方都要用到的,

echo_lovely | 园豆:1546 (小虾三级) | 2020-05-28 10:15

图像识别是一个线程,这个info就是在图像识别线程里的,识别结果
另一个负责调用paint方法,将识别的结果展示在picturebox中,所以就用了两个线程

echo_lovely | 园豆:1546 (小虾三级) | 2020-05-28 10:17

@小草上飞飞: 公共变量就是麻烦
在线程B,直接调用className.info.ToArray()试一下,ToArray方法应该比遍历Keys靠谱一些

拓拓 | 园豆:1055 (小虾三级) | 2020-05-28 10:25

@拓拓: 你看我其他的提问,我都要哭了,多线程这个ConcurrentDictionary问题,前几个问题是别人代码里的,直接从别的系统摘出来给我。我搞了好久,勉强暂时不出问题,运行时间长了就down了,我一个学Java的做C#还是有些麻烦

echo_lovely | 园豆:1546 (小虾三级) | 2020-05-28 10:37

@拓拓: 按道理,ToArray()应该是不会出问题,因为保存的是当时的副本

echo_lovely | 园豆:1546 (小虾三级) | 2020-05-28 10:38

@小草上飞飞: 讲道理你这一个线程写一个线程读的场景就不该用ConcurrentDictionary,这里如果用一个ConcurrentQueue存数据,你就不需要考虑字典的更新问题。
然后上游搞出来的数据有没有问题一目了然。
这样看起来才合理一点。

多线程的东西,要尽可能的避免读写同一个变量,如果可以,全都是只读的最好。

拓拓 | 园豆:1055 (小虾三级) | 2020-05-28 10:51

@小草上飞飞: 还有,静态全局变量也不是不能替换,就是麻烦一点,需要仔细检查一下

拓拓 | 园豆:1055 (小虾三级) | 2020-05-28 11:00

@拓拓: 可以试一试ConcurrentQueue

echo_lovely | 园豆:1546 (小虾三级) | 2020-05-28 11:03
其他回答(1)
0

简单点就加个锁吧

sweetjian | 园豆:276 (菜鸟二级) | 2020-08-21 15:30
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册