Проблема с не отвечающими темами - PullRequest
0 голосов
/ 02 апреля 2010

У меня есть веб-приложение, которое запускает несколько потоков по нажатию кнопки, каждый поток выполняет IO-вызов для разных ipAddresses, т. Е. (Вход в учетную запись Windows, а затем выполнение файловых операций). Предельное значение составляет 30 секунд. Я предполагаю, что при попытке входа в систему, если превышен порог, устройство на ipAddress не соответствует моим условиям, поэтому мне все равно. Thread.Abort () не подходит для моей ситуации, когда он ожидает завершения вызова IO, что может занять много времени.

Я пытался выполнять операции с БД в соответствии с состояниями потоков сразу после истечения времени ожидания. Это работало нормально, но когда я извлек файл журнала, я заметил, что свойство thread.IsAlive несоответствующих потоков все еще имело значение true. После нескольких отладок на моем локальном компьютере я столкнулся с возможной тупиковой ситуацией (которую я подозреваю), что мой компьютер вышел из строя сильно.

Короче говоря, у вас есть идея убить (принудительно) не отвечающие потоки (в ожидании операции ввода-вывода) сразу после выполнения button_click?

(PS: я не использую пул потоков)

Oguzhan

EDIT

Для дальнейшего уточнения,

Мне нужно проверить указанные учетные данные локального администратора на каждом ipAddress и вставить запись в БД для последующих. Остальное мне все равно.

В моем методе проверки я сначала вызвал метод logonuser из win32, импортировав advapi32.dll для олицетворения пользователя-администратора. После этого я пытаюсь создать временный каталог на удаленном системном диске с помощью метода Directory.CreateDirectory просто для проверки авторизации. Если было сгенерировано какое-либо исключение (UnauthorizedAccessException или IOException), тогда удаленный компьютер не представляет интереса, иначе мы его получили, поэтому вставьте в БД.

Я назвал метод проверки синхронным способом для данного диапазона IP-адресов, и он отлично работал для нескольких последовательных конечных точек. Но когда я тестировал метод для какого-то неуместного диапазона ipAddress, каждая попытка валидации длилась от 20 секунд до 5 минут.

Затем я превратил свой дизайн в многопоточный режим, в котором я решил запустить каждую проверку в отдельном потоке и прервать не отвечающие потоки в конце порогового значения. Проблема была в том, что thread.abort не очень хорошо подходил к ситуации, которая фактически ожидает возврата инструкции IO (что я не хочу) и после этого вызывает исключение ThreadAbortException.

Чтобы завершить выполнение последовательных потоков, я проигнорировал не отвечающие потоки и продолжил операции с БД и вернулся из метода нажатия кнопки (не отвечающие потоки были все еще живы в тот момент). Все казалось нормальным, пока я не получил сбой системы после нескольких нажатий кнопки (в режиме отладки). Проблема, вероятно, заключалась в увеличении числа живых потоков в службе IIS.

РЕШЕНИЕ

Причиной того, что потоки не отвечают своевременно, является ситуация, когда сетевой путь не найден. Мое решение состоит в том, чтобы проверить подключение через TCP на порт 135 (порт 135 является обязательным для RPC на окнах) перед выполнением вызова IO. Период ожидания по умолчанию составляет 20 секунд. Если вам нужно установить тайм-аут, используйте BeginConenct. Другой вариант - Pinging (если ICMP включен в сети)

1 Ответ

1 голос
/ 02 апреля 2010

Зачем вам вообще нужно прерывать потоки? Почему бы просто не дать им нормально завершиться, а проигнорировать результаты? (Сохраните токен, чтобы указать, в каком «пакете» запросов он находится, а затем запомните, какой именно пакет в данный момент вам действительно интересен.)

Другой вариант - сохранить все, что вы используете, чтобы сделать IO-вызов (например, сокет) и закрыть его; это должно вызвать исключение в потоке, выполняющем запрос.

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

...