我有一个应用程序,其中有一个可由多个客户端访问的共享资源(运动系统)。我有一些单独的操作,需要在移动期间访问系统,并且如果同时请求冲突的操作,则应抛出“繁忙”异常。我还有序列器,它们需要获得对运动系统的独占访问权限,以执行多个操作,并穿插其他操作;在整个序列期间,任何其他客户端都不应能够运行操作。
我传统上使用线程亲和性来解决这个问题,以便线程可以请求独占访问并运行与操作相对应的阻塞调用。当线程具有访问权限时,其他线程不能使用该资源。我现在遇到的问题是,我已经转向使用异步/等待模式来实现我的系统,以允许更清晰的排序器实现。问题是现在我的定序器并不总是在同一个线程上运行;活动线程可以在回调过程中发生变化,因此不再容易确定我是否处于有效的上下文中以继续运行操作。值得注意的一点是,某些操作本身是由等待组成的,这意味着序列和单个操作都可以跨越多个线程。
我的问题:有人知道在由于异步/等待而发生线程切换的情况下处理获取独占访问的好模式吗?
作为参考,我考虑了一些事情:
我可以创建一个自定义 SynchronizationContext,它将序列持续时间内的所有定序器调用封送到单个线程。这样做的好处是允许我重用现有的线程亲和性访问管理代码。缺点是,每当我执行序列或操作时,这都需要专用一个线程(因为操作也可以跨越多个线程。)
创建可获取的访问令牌以传递给操作方法以证明您已获取访问权限。这样做的缺点是使用令牌参数会使方法变得臃肿。
使用 (2) 中的访问令牌方法,但为操作接口创建重复的接口实现,以便可以使用“内置”令牌来实例化包装器。这会创建一些丑陋的粘合代码,但它清理了定序器代码,以便不再需要向每个方法传递令牌。
我的问题:有人知道在由于异步/等待而发生线程切换的情况下处理获取独占访问的好模式吗?
是的,您可以使用AsyncLock http://blogs.msdn.com/b/pfxteam/archive/2012/02/12/10266988.aspx,这也可以作为我的一部分AsyncEx 库 https://github.com/StephenCleary/AsyncEx。如果您想要进行“TryLock”类型的操作,那么您可能必须创建自己的原语。
您确实失去了一些进行安全检查的能力:无法检查当前正在执行的线程是否具有特定的AsyncLock
.
其他选项包括ConcurrentExclusiveSchedulerPair
(我在博客上提到过here http://nitoprograms.blogspot.com/2012/08/async-and-scheduled-concurrency.html)或 TPL 数据流。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)