2008-11-29 100 views
2

我正在编写一个服务,它有五种不同的方法,可能需要5秒到5分钟才能运行。强制服务中的线程等待另一个线程完成

该服务将安排这些不同的方法以不同的间隔运行。

我不希望任何方法同时运行,那么如何让方法检查另一个方法是否正在运行并排队等待它自己运行?

安东尼

+0

你在用什么语言编码? – 2008-11-29 11:25:51

回答

5

如果你想简单,所有的方法都在同类,OU可以只使用[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]的特定模式定义为“有效”,甚至包括私有锁的示例。但是,MS规范坚持这种/类型。

1

如果您使用的是Java,可以使方法synchronized,这将阻止多个线程同时访问它。

4

还有MethodImplOptions.Synchronized attribute,如 文章Synchronized method access in C#所述,但可能会导致死锁,如MSDN所述。这听起来像是因为你的使用,这不会是一个大问题。

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

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

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

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

死锁与私人锁定一样,与[MethodImpl]一样 - 只是知道哪些代码可能会访问锁定有点困难。 – 2008-11-29 12:55:54

0

通常,我强烈建议不要使用MethodImpl(MethodImplOptions.Synchronized)属性来执行线程同步。如果你打算做多线程编程,你应该仔细考虑你应该在哪里以及如何锁定。

我可能会夸大一点,但我发现MethodImpl同步方法和其他方法之间存在太多相似之处,比如VB中使用End语句。它常常表明你并不知道自己在做什么,并希望这个陈述/方法/属性能够神奇地解决你的问题。