我有一个应用程序,其中有一个共享资源(运动系统),可以由多个客户端访问。我有个别操作需要在移动期间访问系统,如果同时请求冲突操作,则应该抛出“忙碌”异常。我也有 Sequencer,需要获得对 Motion 系统的独占访问权限以执行多个操作,并穿插其他操作;在整个序列中,没有其他客户端应该能够运行操作。
我传统上使用线程关联来解决这个问题,以便线程可以请求独占访问并运行与操作相对应的阻塞调用。虽然线程具有访问权限,但没有其他线程可以使用该资源。我现在遇到的问题是我已经转向使用 async/await 模式来实现我的系统,以允许更清晰的序列器实现。问题是现在我的定序器并不总是在同一个线程上运行;活动线程可以在回调过程中发生变化,因此不再容易确定我是否处于有效的上下文中以继续运行操作。需要注意的一点是,一些操作本身是由等待组成的,这意味着序列和单个操作都可以跨越多个线程。
我的问题:有没有人知道一个很好的模式来处理由于异步/等待而在线程切换的情况下获取独占访问?
作为参考,我考虑了一些事情:
我可以创建一个自定义 SynchronizationContext,它将序列持续时间内的所有定序器调用编组回单个线程。这样做的好处是允许我重用现有的线程关联访问管理代码。不利的一面是,每当我执行序列或操作时,这都需要专用线程(因为操作也可以跨越多个线程。)
创建一个可获取的访问令牌以传递给 Operation 方法,以证明您已获得访问权限。这具有使用令牌参数使方法膨胀的缺点。
使用 (2) 中的访问令牌方法,但为操作接口创建一个重复的接口实现,以便可以使用令牌“烘焙”来实例化包装器。这会创建一些丑陋的胶水代码,但它会清理序列器代码,以便不再需要将令牌传递给每个方法。