与超时锁定模式 [英] Locking with timeout pattern

查看:329
本文介绍了与超时锁定模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

锁定使用此模式。

if(Monitor.Enter(lock))
    try
    {
        ...
    }
    finally { Monitor.Exit(lock); } // using this style to reduce post "height"

如果我们不希望等待无限我们可以提供超时

if we don't want to wait infinite we can provide timeout

if(!Monitor.TryEnter(lock, timeout))
    throw new TimeoutException();
try
{
    ...
}
finally { Monitor.Exit(lock); }



我有方案时,方法来获得多个锁才开始做任何事情。这看起来可怕的:

I have scenario when method has to obtain multiple locks before it start doing anything. This looks awful:

if(!Monitor.TryEnter(lockA, timeout))
    throw new TimeoutException();
try
{
    if(!Monitor.TryEnter(lockB, timeout))
        throw new TimeoutException();
    try
    {
        if(!Monitor.TryEnter(lockC, timeout))
            throw new TimeoutException();
        try
        {
            ... // more of such constructions
        }
        finally { Monitor.Exit(lockC); }
    }
    finally { Monitor.Exit(lockB); }
}
finally { Monitor.Exit(lockA); }



它有问题:

It has problems:


  • 相貌丑陋(方法代码缩进,想象它怎么会查找 lockZ ),可以通过将法码到另一种方法来解决

  • looks ugly (the method code is indented, imagine how it will looks for lockZ), can be solved by putting method code into another method.

锁定同步发生,所以最坏的成功的案例可能需要时间比所有超时的总和略少。

locking occurs synchronously, so the worst successful case may take time slightly less than a sum of all timeouts.

有没有办法改善这种超时模式的方法是什么?

Is there a way to improve this timeout pattern?

我想做出一个方法,委托参数和锁定,实现像LINQ链(但并行也跑锁,这是一个挑战):

I was thinking to make a method with delegate parameter and lock to achieve something like linq chaining (but to also run locks in parallel, this is a challenge):

Lock(lockA).Lock(lockB).Lock(lockC).Run( () => ...);



或者,也许有另一种方式?

Or perhaps there is another way?

推荐答案

我会去与usings的同步锁定:

I would go with usings for sync lock:

public class MyLock : IDisposable
{
     private object lockObj;
     public MyLock(lockObj)
     {
          this.lockObj = lockObj;
          if(!Monitor.TryEnter(this.lockObj, timeout))
              throw new TimeoutException();
     }

     public void Dispose()
     {
           Monitor.Exit(lockObj)
     }
}

Uasge:

using(new MyLock(lockA))
using(new MyLock(lockB))
using(new MyLock(lockC))
{
    // your code
}

不知道是不是锁定,在构造函数的良好格局/设计,但它的工作;)

Do not know if "locking" in ctor is good pattern / design, but it will work ;)

有关异步。 Parralization是不是好主意。为什么?
。如果某个线程将进入显示器,同样的线程必须让它(退出带锁)。所以,如果你锁定 objA Parallel.ForEach (远东)你不知道哪个线程已经做到了。所以,你将无法将其释放。

For async. Parralization is not good idea. Why? If some thread will enter the monitor, the same thread must leave it (exit with lock). So if you lock on objA within Parallel.ForEach (f.e.) you will not know which thread has done it. So you won't be able to release it.

这篇关于与超时锁定模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆