Problem with the nonresponding threads
I have a web application which runs multiple threads on button click each thread making IO call on different ipAddresses ie(login windows account and then making file operations). There is a treshold value of 30 seconds. I assume that while login attempt if the treshold is exceeded, device on ipAddress does not match my conditions thus I dont care it. Thread.Abort() does not fit my situation where it waits for the IO call to finish which might take long time.
I tried doing the db operations acording to states of the threads right after the treshold timeout. It worked fine but when I checked out the log file, I noticed that the thread.IsAlive property of the nonresponding threads were still true. After several debuggings on my local pc, I encountered a possible deadlock situation (which ı suspect) that my pc crashed badly.
In short, do you have any idea about killing (forcefully) nonresponding threads (waiting for the IO opreation) right after the execution of the button_click?
(PS: я не использую пул потоков)
Oguzhan
РЕДАКТИРОВАТЬ
Для дальнейшего уточнения,
Мне нужно проверить указанные учетные данные локального администратора на каждом ipAddress и вставить запись в БД для последующих. В остальном мне все равно.
В моем методе проверки я сначала вызвал метод logonuser из win32, импортировав advapi32.dll для олицетворения пользователя-администратора. После этого я пытаюсь создать временный каталог на удаленном системном диске с помощью метода Directory.CreateDirectory просто для проверки авторизации. Если было сгенерировано какое-либо исключение (UnauthorizedAccessException или IOException), тогда удаленный компьютер не представляет интереса, иначе мы его получили, поэтому вставили в БД.
Я назвал метод проверки синхронным способом для заданного диапазона IP-адресов, и он отлично работал для нескольких последовательных конечных точек. Но когда я тестировал метод для какого-то несоответствующего диапазона ipAddress, каждая попытка валидации занимала от 20 секунд до 5 минут.
Затем я превратил свой дизайн в многопоточный режим, в котором я решил запустить каждую проверку в отдельном потоке и прервать не отвечающие потоки в конце порогового значения. Проблема была в том, что thread.abort не очень хорошо подходил к ситуации, которая фактически ожидает возврата инструкции IO (чего я не хочу) и после этого вызывает исключение ThreadAbortException.
Чтобы завершить выполнение последовательных потоков, я проигнорировал несоответствующие потоки и продолжил операции с БД и вернулся из метода нажатия кнопки (несоответствующие threds были все еще живы в тот момент). Все казалось нормальным, пока я не получил сбой системы после нескольких нажатий кнопки (в режиме отладки). Проблема, вероятно, заключалась в увеличении числа живых потоков в службе IIS.
РЕШЕНИЕ
Причиной того, что потоки не отвечают своевременно, является ситуация, когда сетевой путь не найден. Мое решение состоит в том, чтобы проверить подключение через TCP на порт 135 (порт 135 является обязательным для RPC на окнах) перед выполнением вызова IO. Период ожидания по умолчанию составляет 20 секунд. Если вам нужно установить тайм-аут, используйте BeginConenct. Другим вариантом будет Pinging (если ICMP включен в сети)
1 ответ
Почему вы действительно должны прервать потоки в любом случае? Почему бы просто не дать им закончить нормально, а проигнорировать результаты? (Сохраните токен, чтобы указать, в каком "пакете" запросов он находится, а затем запомните, какой пакет на самом деле вас интересует в данный момент.)
Другой вариант - сохранить все, что вы используете, чтобы сделать IO -вызов (например, сокет) и закрыть его; это должно вызвать исключение в потоке, делающем запрос.
Еще один вариант - избежать размещения запросов в разных потоках, но вместо этого использовать асинхронный ввод-вывод - вы все равно получите параллелизм, но без привязки потоков (только порты завершения ввода-вывода). Кроме того, вы не можете установить тайм-аут на саму операцию ввода-вывода? Таким образом, запрос должен просто истекать.