English 中文(简体)
强制服务中的线程等待另一个线程完成
原标题:
  • 时间:2008-11-29 11:23:24
  •  标签:

我正在编写一个服务,它有五种不同的方法,这些方法的运行时间在5秒到5分钟之间。

这项服务将安排不同的方法在不同的时间间隔内运行。

我不想让任何方法并发运行,那么我该如何让这些方法检查是否有其他方法正在运行,然后在其完成后排队运行?

安东尼

最佳回答

如果你想要“简单”,并且所有的方法都在同一个类中,你可以只使用[MethodImpl]:

[MethodImpl(MethodImplOptions.Synchronized)]
public void Foo() {...}

[MethodImpl(MethodImplOptions.Synchronized)]
public void Bar() {...}

例如对于实例方法,这个锁定在 this 上;对于静态方法,这个锁定在 typeof(TheClass) 上。

因此,这些锁对象是公开的 - 所以有一个远程(但真实的)机会,另一个代码段可能会锁定它们。通常认为最好的实践是创建自己的锁对象:

private readonly object syncLock = new object(); // or static if needed

...
public void Foo() {
   lock(syncLock) {
      ...
   }
}

等等


附带说明一个有趣的事实;ECMA规范没有为[MethodImpl]定义特定的模式,甚至包括一个私有锁的示例也被认为是“有效”的。然而,微软规范坚持要求采用这种/typeof形式。

问题回答

There s the MethodImplOptions.Synchronized attribute, as noted in the article Synchronized method access in C#, but that can lead to deadlocks as noted at MSDN. It sounds like, for your usage, this won t be a big concern.

否则,最简单的方法是使用lock语句确保只有一个方法在同一时间执行:

class ServiceClass
{
     private object thisLock = new object();

     public Method1()
     {
        lock ( thisLock )
        {
             ...
        }
     }

     public Method2()
     {
        lock ( thisLock )
        {
             ...
        }
     }
     ...
}

如果你正在使用Java,你可以使方法同步,这将防止多个线程同时访问。

总的来说,我强烈不建议使用MethodImpl(MethodImplOptions.Synchronized)属性来进行线程同步。如果你要进行多线程编程,你真的应该非常仔细地考虑在哪里和如何进行锁定。

我可能有点夸张,但是我发现MethodImpl同步方法与其他方法(如在VB中使用End语句)存在太多相似之处。这经常向我传达一种信息,即您并不真正知道自己在做什么,并希望这种语句/方法/属性可以神奇地解决您的问题。





相关问题
热门标签