Коммуникация C# между потоками

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

У меня есть сервис окон, который имеет очень интенсивный процесс, который всегда работает, я поместил этот процесс на отдельный поток так, чтобы основной поток моего сервиса мог справиться с операционными задачами - т.е. сервисные циклы аудита, обработав изменения конфигурации, и т.д., и т.д.

Я запускаю поток через типичный ThreadStart к методу, который начинает, процесс - называют это workerthread.

На этом workerthread я отправляю данные на другой сервер, как ожидается, перезагрузки сервера время от времени и соединение потеряны, и я должен восстановить соединение (я уведомляюсь потерянным из соединения через событие). Отсюда я делаю мой повторно подключать логику, и я вернулся в и выполнение, однако что я легко начал замечать для случая, был то, что я создавал этот рабочий поток много раз каждый раз, когда (не, что я хочу).

Теперь я мог уничтожить workerthread, когда я теряю соединение и запускаю новое, но это походит на трату ресурсов.

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

Отправьте любые примеры или документы, которые Вы имеете, который был бы полезен.

Спасибо.

9
задан GT. 13 April 2010 в 01:08
поделиться

6 ответов

Рассматривали ли вы BackgroundWorker ?

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

1
ответ дан 4 December 2019 в 22:28
поделиться

Я бы все равно убил (но закончил аккуратно, если возможно) рабочий поток. Все будет собрано в мусор, и вы сможете начать с нуля.

Как часто происходит перезагрузка сервера? Если это происходит достаточно часто, чтобы ресурсы были проблемой, это, вероятно, происходит слишком часто.

1
ответ дан 4 December 2019 в 22:28
поделиться

Вам следует избегать убийства рабочего потока. Когда вы принудительно убиваете поток Win32, не все его ресурсы полностью восстанавливаются. Я полагаю, что зарезервированное виртуальное адресное пространство (или это корневая страница?) для стека потоков не восстанавливается при убийстве потока Win32. Возможно, это не так много, но в долго работающем процессе серверной службы это будет накапливаться со временем и в конечном итоге приведет к остановке службы.

Если потоку разрешено выйти из своего threadproc для нормального завершения, все ресурсы восстанавливаются.

Если фоновый поток будет выполняться постоянно (не спать), вы можете просто использовать глобальный булев флаг для передачи состояния между основным и фоновым потоком. При условии, что фоновый поток периодически проверяет этот глобальный флаг. Если флаг установлен, поток может чисто выключиться и выйти. Семантика блокировки не нужна, если основной поток является единственным писателем, а фоновый поток только считывает значение флага.

Когда фоновый поток теряет соединение с сервером, на который он отправляет данные, почему бы ему не выполнить повторное соединение самостоятельно? Мне неясно, почему основной поток должен разорвать фоновый поток, чтобы запустить другой.

3
ответ дан 4 December 2019 в 22:28
поделиться

Вызовите метод, используя ThreadPool.QueueUserWorkItem вместо этого. Этот метод захватывает поток из пула потоков и запускает метод. Похоже, он идеально подходит для задачи запуска метода в другом потоке.

Также, когда вы говорите "типичный ThreadStart", вы имеете в виду, что создаете и запускаете новый Thread с параметром ThreadStart, или вы создаете ThreadStart и вызываете Invoke на нем?

.
1
ответ дан 4 December 2019 в 22:28
поделиться

Вы можете использовать паттерн Singleton. В вашем случае сделайте соединение статическим объектом. Оба потока могут получить доступ к объекту, то есть сконструировать его и использовать.

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

1
ответ дан 4 December 2019 в 22:28
поделиться

BackgroundWorker немного медленнее, чем использование простых потоков, но он может поддерживать метод CancelAsync .
По сути, BackgroundWorker - это оболочка рабочего потока с некоторыми дополнительными параметрами и событиями.

Метод CancelAsync работает, только если задано значение WorkerSupportsCancellation .
Когда вызывается CancelAsync , устанавливается CancellationPending .
Рабочий поток должен периодически проверять CancellationPending , чтобы узнать, нужно ли преждевременно завершить работу.

- jeroen

1
ответ дан 4 December 2019 в 22:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: