我正在编写一种服务,它有五种不同的方法可能需要5秒到5分钟才能运行。
该服务将安排这些不同的方法以不同的间隔运行。
我不希望任何方法同时运行,所以我如何检查方法是否正在运行另一个方法并将其自身排队以便在完成时运行?
安东尼
答案 0 :(得分: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]的特定模式定义为“有效”,甚至包括私有锁的示例。但是,MS规范坚持这个/ typeof。
答案 1 :(得分: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 )
{
...
}
}
...
}
答案 2 :(得分:1)
如果您使用的是java,则可以创建方法synchronized,这将阻止多个线程同时访问它。
答案 3 :(得分:0)
通常,我强烈建议不要使用MethodImpl(MethodImplOptions.Synchronized)属性来执行线程同步。如果您要进行多线程编程,您应该非常仔细地考虑确切锁定的位置和方式。
我可能会夸大一点,但我发现MethodImpl同步方法与其他方法之间有太多相似之处,例如在VB中使用End语句。它经常向我发出信号,表示你并不真正知道自己在做什么,并希望这个语句/方法/属性能够神奇地解决你的问题。