Заставить потоки в сервисе ждать завершения другого потока - PullRequest
2 голосов
/ 29 ноября 2008

Я пишу сервис, который имеет пять различных методов, выполнение которых может занять от 5 секунд до 5 минут.

Служба запланирует запуск этих разных методов с разными интервалами.

Я не хочу, чтобы какой-либо из методов запускался одновременно, так как мне заставить методы проверить, запущен ли другой метод, и поставить в очередь саму работу после его завершения?

Anthony

Ответы [ 4 ]

5 голосов
/ 29 ноября 2008

Если вы хотите simple , и все методы находятся в одном классе, вы можете просто использовать [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.

4 голосов
/ 29 ноября 2008

Есть атрибут MethodImplOptions.Synchronized , как отмечено в article Синхронизированный доступ к методам в C # , но это может привести к тупикам, как отмечено в MSDN. Похоже, для вашего использования это не будет большой проблемой.

В противном случае простейшим подходом будет использование оператора lock , чтобы убедиться, что одновременно выполняется только один метод:

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

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

     public Method2()
     {
        lock ( thisLock )
        {
             ...
        }
     }
     ...
}
1 голос
/ 29 ноября 2008

Если вы используете Java, вы можете сделать методы синхронизированными , что предотвратит одновременный доступ к нему нескольких потоков.

0 голосов
/ 29 ноября 2008

В общем, я настоятельно не рекомендую использовать атрибут MethodImpl (MethodImplOptions.Synchronized) для синхронизации потоков. Если вы собираетесь заниматься многопоточным программированием, вам действительно следует очень тщательно продумать, где именно и как вы должны блокировать.

Возможно, я немного преувеличиваю, но нахожу слишком много общего между методом синхронизации MethodImpl и другими, такими как использование оператора End в VB. Мне часто дают понять, что вы на самом деле не знаете, что делаете, и надеетесь, что это утверждение / метод / атрибут волшебным образом решит вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...