首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >锁对Interlocked.Exchange

锁对Interlocked.Exchange
EN

Stack Overflow用户
提问于 2015-08-20 14:58:24
回答 2查看 3.1K关注 0票数 2

我有一个应用程序,它经常(+-100 in )读取来自PLC的订单,然后将它们放入一个模型中,然后由多个客户端读取。对于此im,使用lock语句。

订单阅读线程:

代码语言:javascript
复制
lock (model) {
//update object
}

客户阅读:

代码语言:javascript
复制
lock (model) {
//serialize object to json string
}
send over tcp stream to client.

但我也可以用来更新:

代码语言:javascript
复制
Interlocked.ExChange(oldObj, newObj)

我不希望我的客户端必须等待发生在Order线程中的锁。我绝对不希望客户阻止我的订单阅读线程。

我还是用联锁好吗?

谢谢你的建议!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-20 15:08:36

是的,您最好使用Interlocked,因为它更高效,因为它大多被转换成一个原子操作。

但是,如果您不介意客户机仍然读取旧对象,那么您甚至可以不使用互锁,只需设置一个新实例。

碰巧得到新实例的客户端将获得更新的数据,而那些没有得到更新数据的客户端将在下一次检查中获得数据。

票数 5
EN

Stack Overflow用户

发布于 2015-08-20 15:08:43

如果您的单个生产者正在创建一个全新的模型,并将其分配给一个共享字段,那么是的,Interlocked.Exchange就是这里的方法。

如果您的生产者不需要知道旧模型是什么,那么您可以使用Volatile.Write(ref _sharedObj, newObj)来简化它。

只要注意三件事:

  1. 使用Volatile.Read读取共享对象。
  2. 使用者应该每工作单位读取一次共享状态。 //不正确- _sharedObj不能保证在两种读取变量x= CalculateX(_sharedObj);var y= CalculateY(_sharedObj);//更正var obj = Volatile.Read(ref _sharedObj);var x= CalculateX(obj);var y= CalculateY(obj);
  3. 消费者有时会使用一种稍微过时的模式。因此,请确保使用稍微过时的对象不会给您带来任何麻烦。 var obj = _sharedObj;//如果在这里交换_sharedObj,那么obj将过时,var x= CalculateX(obj);var y= CalculateY(obj);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32121684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档