c# - 当“真相源”具有通用多个操作时如何同步访问
问题描述
我有一个项目存储库,用于视图模型(主线程)和后台服务(后台线程)。两者都可以查询项目存储库和更新项目。
class ItemRepository
{
Item GetItem(int id);
void UpdateItem(Item item);
}
public class Item
{
ItemState State { get; set; }
}
// Component A (view-model)
// Runs on main thread
void ExecuteUpdateItemCommand()
{
var item = _itemRepo.GetItem(1);
if(item.State == ItemState.First)
{
itemState.State = ItemState.Second;
_itemRepo.UpdateItem(item); // Ideally this should be on a separate thread but for now lets' assume it's on main thread
}
}
// Component B (background service - receives notifications from backedn)
// Runs on a background thread
void OnNotificationReceived()
{
var item = _itemRepo.GetItem(1);
if(item.State == ItemState.First)
{
item.State = GetNextState(); // some busines logic specific to Component B
_itemRepo.UpdateItem(item);
}
}
我遇到的问题是在两个线程之间实现项目查询和更新的同步。
如果没有同步,item 的状态可能会损坏,因为 if 语句在一个线程上返回后,另一个线程可能正在将 item 状态更新为另一个值,这可能会破坏 item 状态的业务逻辑。
一个简单的解决方案是让组件 A 和组件 B 锁定在同一个共享对象上。从设计的角度来看,如何在组件之间共享这个对象(每个组件都有不同的目的)?
我看到的另一个解决方案是为了同步调用而拥有一个同时执行组件 A 和组件 B 的业务逻辑的服务,但我认为这不是一个好的解决方案。
我正在寻找比这些更好的实现。
我的感觉是一个很好的解决方案可能是一个允许我在上下文中运行事物的解决方案。就像是
ItemSyncContext.Run(ExecuteUpdateItemCommand);
和
ItemSyncContext.Run(OnNotificationReceived);
解决方案
理想情况下,您只需调用一次即可完成这两项更新的服务。如果这不是一个选项,您需要回答“更新何时发生?”的问题。在服务中。如果调用是阻塞的,所以在调用返回之前提交更新,你可以安全地保持你的代码原样。否则,您需要研究某种机制(即锁定)以确保调用以正确的顺序发生。
推荐阅读
- sequelize.js - 续集 findOne 返回 null 然后模型为空
- php - 表单中的表单,PHP
- java - 我需要帮助确定在 Mac 上使用 RL4J 在 Anylogic PLE 中导致控制台调试垃圾邮件的问题
- java - 是否可以将 Hazelcast 客户端 4.1 与版本 3 的服务器一起使用?
- python - PyMongo:2秒递归时间延迟
- c# - 无法模拟 HttpRequestBase 中的查询字符串以进行单元测试
- ionic-framework - Ionic 5 / Capacitor:如何确定应用程序是在浏览器中运行还是编译为本机应用程序?
- python - 我怎样才能为每两个值做比较运算符?
- node.js - 从 azure web 应用程序向我的机器发送 http 请求
- r - 如何更改 tesseract 配置以识别§并在 R 中使用 pdftools::pdf_ocr_text 应用?