2013-05-07 4 views
0

У меня есть планировщик, который работает как фоновый поток при запуске приложения на сайте ASP.NET. Пользователь может инициировать различные задачи (оповещение по электронной почте/генерация файлов и т. Д.), Которые вставляются в таблицу db. Планировщик выберет задачи из базы данных и перетащите элементы в стек. Кроме того, у планировщика есть threadpool, в котором запущено 10 фоновых потоков, которые будут вызывать элементы задачи из стека и выполнять его.Почему потоки C# простаивают во время выполнения?

Это работает отлично на одном веб-сервере, но ведет себя странно на другом веб-сервере. Нитки простаивают в течение 6-12 секунд без каких-либо оснований и ничего не делают, даже если в стеке есть предметы.

  • Использование блокировки() на объекте стека, чтобы сделать принудительную & Pop Потокобезопасной
  • Пробовал Thread.yield(), чтобы дать выход для центрального процессора для выполнения других потоков, но замедляет выполнение и происходят в режиме ожидания все еще сохраняется
  • Tried Thread.Sleep (0), чтобы дать доход процессору для выполнения других потоков, но замедление выполнения и простаивания по-прежнему сохраняется
  • Записанные записи и выход из всех методов, чтобы проверить, что-то не так во время выполнения, но нет удачи

Мои вопросы:

  1. Является ли исполнение потоков в .net в детерминированным?
  2. Нужно ли указывать Thread.Yield() или Thread.Sleep (0), чтобы дать время для дыхания к процессору?
  3. Почему он ведет себя по-разному на коробках с одинаковой конфигурацией? Существуют ли какие-либо факторы, связанные с машиной/средой, которые влияют на выполнение потока?

UPDATE на May.08.2013

Есть две коробки в ферме, оба идентичны в аппаратной конфигурации, установки с такой же конфигурацией программного обеспечения, а также для Windows 2008 64bit/IIS7. Оба веб-сервера имеют только один сайт с одинаковой компоновкой. Пулы приложений обоих сайтов работают на платформе V4.0 в интегрированном режиме. Это устаревший код и никаких шансов с двух последних лет.

Мы пробовали несколько итераций, во всех случаях webserver1 выполняется без каких-либо проблем и быстро завершает работу фона, как это было раньше. BUT webserver2 имеет значительную задержку и работает очень плохо.

Мы пробовали обширную регистрацию, захватывая записи/вывод всех методов. Сценарий подобен этому, все потоки отлично работают в течение 2 секунд, а затем простаивают в течение 6-12 секунд, снова становятся живыми и выполняются в течение следующих 2 секунд, а затем снова простаивают. Это поведенческое поведение является последовательным до завершения задания. Исключение не исключение, отсутствие приложения, отсутствие ошибки в журнале пула приложений/iis.

Любая идея?

+3

1. Да. 2. № 3. Вероятно, у вас есть условие ошибки/гонки, которое может создать только одна конфигурация; не зная больше о коде, это трудно понять наверняка. – Servy

+0

@Servy Почему выполнение потока замедляется при использовании Thread.Yield() или Thread.Sleep (0)? – eka

+0

@Servy оригинальный код сложный, однако я обновил вопрос с помощью фальшивого кода. – eka

ответ

0

Хорошо, ребята, наконец, мы прикрепили проблему.

Один из ядро ​​процессора веб-сервера попал на 100% и никогда не возвращается. В то время как другие ядра составляют 0-5%.

Мы выполнили нагрузочное тестирование для нормальных - умеренно тяжелых грузов. При создании нормальной и умеренной нагрузки сервер обслуживает прилично, правильно распределяя выполнение процесса со всеми другими ядрами процессора. Но когда мы генерируем большую нагрузку, ситуация меняется, сервер борется за распределение нагрузки между ядрами, а поток простаивает в течение 6-7 секунд. Мы предполагаем, что из-за отказа одного ядра процессора он имеет дело с некоторой нечеткой логикой для распределения процесса между ядрами.

После дальнейшего расследования мы обнаружили, что ядро ​​Windows NT вызывает эту проблему, возможно, из-за проблемы с коррупцией или драйвером.

0

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

Вы можете использовать AutoResetEvent и дождаться его в рабочих потоках - и Set событие, когда вы нажимаете элемент для стека.

+0

nop, я так не думаю, что мы зарегистрировали записи, и выход методов и операторов блокировки находится внутри вызова метода. он даже не прибегает к методу. Кроме того, я мог бы использовать событие autoreset для уведомления друг друга, если было всего два потока. В моем случае есть несколько потоков (10), просматривающих стек. Я не могу вызвать сброс, чтобы уведомить конкретный поток – eka

+0

Извините, не получил смысла «его даже не прибегает к методу». – YK1

+0

Операторы записи отладки не будут напечатаны, если вы используете исполняемые файлы выпуска. Вместо этого используйте 'Trace'. Все 10 потоков могут ждать один AutoResetEvent. Когда вы подталкиваете один элемент к стеку, вызывайте 'Set'. Один из ожидающих потоков будет освобожден и обработан.Нет необходимости называть 'Reset' – YK1

Смежные вопросы