Статический семафор передан как член класса Thread instance = bug? - PullRequest
0 голосов
/ 27 октября 2009

В нашей базе кода есть несколько проектов службы Windows, которые следуют этой модели, и я просто хочу убедиться, что это не ошибка.

В этой модели есть как минимум один статический класс «таймера», управляемый System.Timers.Timer, который извлекает пакеты данных для обработки из базы данных. Semaphore инициализируется как статический член. После получения пакета работы создается новый экземпляр рабочего потока для обработки каждой строки или элемента списка, а потоки управляются статическим семафором родительского класса таймера.

internal class BatchTimer
{
  private static Semaphore m_sem = new Semaphore(Settings.Default.ThreadCount, 
     Settings.Default.ThreadCount);
  private static System.Timers.Timer m_timer = new System.Timers.Timer();

  internal static void DoWork(object source, ElapstedEventArgs e)
  { 
    List<WorkRow> work = Work.GetBatch(Settings.Default.ObjectsPerIteration);
    foreach (WorkRow row in work)
    {
      WorkerThread worker = new WorkerThread
      {
        Semaphore = m_sem,
        Work = row
      };    
      Thread thread = new Thread(worker.Run);
      // Release() is called in finally block of WorkerThread.Run.
      m_sem.WaitOne(); 
      thread.Start();
    }
  }
}

Статическое Semaphore из класса таймера передается члену класса рабочего потока, а не вызову Release рабочего потока () в семафоре родительского класса таймера. Я думаю, что предполагалось, что это будет работать, так как это ссылочный тип. Но мой вопрос: не помешает ли это сборке мусора?

1 Ответ

1 голос
/ 27 октября 2009

В общем, у вас есть GCRoot для работника до тех пор, пока поток, который вы назвали worker.Run on, хорошо работает. Когда метод Run заканчивается, работник становится кандидатом на сборку мусора (поскольку на него больше нет ссылок ни в основном потоке, ни в каком-либо рабочем потоке).

Рабочий получает ссылку на мьютекс, но у вас возникнет проблема только в том случае, если это будет наоборот (наличие статической переменной, содержащей ссылку на вашего работника).

Итак, в основном, GC позаботится о вашем работнике.

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

...