并发访问带有缓存的WebService出现的错误

来源:互联网 发布:条顿森林堡战役知乎 编辑:程序博客网 时间:2024/05/11 22:17
前一段时间,项目组在开发过程中发现,在同一个页面使用两个HSCombobox同时访问一个WebService时会报错。根据项目组​的反馈,我在系统框架的示例项目中做了重现,跟踪源代码时发现,报错的位置在HSEntityWebValidator的_cache.Add(typeName, validator);,提示信息为未将对象引用设置到对象实例。刚开始看到这个信息很迷茫,觉得无从下手,后来反复看了一下系统框架中的代码,发现系统框架中使用了全局静态变量Dictionary。
查阅相关资料后,了解到Dictionary类型为弱引用类型,当没有对象调用的时候,弱引用类型会被.Net的垃圾回收机制自动回收以避免内存溢出,回收之后再去引用这个对象就找不到这个对象了,所以会报这个错误。

但这并不是引发错误的根本原因,根据项目组的描述,应该是多个线程并发访问Dictionary导致的报错,作为全局的静态变量在多线程中是共享的,而Dictionary本身也是非线程安全的。但根据项目组的描述我在一个页面上使用两个HSCombobox访问同一个WebService没有出现异常,于是我在测试项目中模拟了并发的场景来验证我的猜测:

   Parallel.For(1, 100, k =>     {        HSDTOWebModels.GetWebModel(typeof(UserDTO));    });


    测试结果抛出异常……据推测可能是并发线程数量较少,.Net自己优化了线程导致的不报错。


    找到了问题的原因,查找解决方案。在C# 4.0之前,解决线程安全问题的方式是通过Lock的方式来处理的。而我们的系统框架所使用的C#版本为C# 5.0,解决问题的办法也应该有所创新。在C# 4.0以后,.Net提供了一个ConcurrentDictionary,它是线程安全的,于是就用它替换了Dictionary类型,测试发现问题解决。

    但其能否完全替代Dictionary+Lock的方式保证线程安全,这个还有待于进一步验证。
0 0
原创粉丝点击