Примите это во внимание - это не прямой ответ на ваш вопрос, а скорее совет по дизайну, чтобы не попасть в вашу ситуацию. Если ваше приложение действительно заблокировано и не отвечает, то на самом деле нет способа обнаружить его и ответить. Хитрость в том, чтобы сначала не попасть в ситуацию.
По моему опыту, приложения WinForms почти никогда не перестают отвечать. Вместо этого они имеют тенденцию казаться не отвечающими при выполнении длительных задач или попадании в бесконечные (или, по крайней мере, длительные) циклы.
Вы можете избежать этого, поместив долго выполняющиеся процессы в другой поток, используя методы многопоточности. Уловка, которая работает для длинных циклов, состоит в том, чтобы поместить код
Application.DoEvents()
внутри петли. Это позволит приложению отображаться отзывчиво во время работы цикла, когда оно обычно выглядит заблокированным.
Обычно я справляюсь с этим, имея метку состояния, которую я постоянно обновляю, чтобы пользователь знал, что приложение выполняет что-то вроде следующего:
foreach(DataRow r in myTable.Rows)
{
StatusLabel.Text = "Now processing " + r[0].ToString();
Application.DoEvents();
... now do the real work
}
Это дает пользователю обратную связь, чтобы сообщить им, что приложение на самом деле что-то делает, а не просто «заблокировано». В 99% случаев восприятие пользователя - все, что имеет значение.
Изменить - добавлено для ответа на комментарий ниже
Application.DoEvents () включает , включая снижение производительности. Вы должны решить, стоит ли это того. Используемый, как я показал выше (в сочетании с каким-то индикатором прогресса), он может устранить разочарование пользователей, и я считаю, что он является достойным компромиссом для длительных процессов.
В моем первоначальном ответе упоминалось, что восприятие - это все, что имеет значение в 99% случаев. Я приведу пример, где я использовал это и чувствовал, что это оправдано.
Я унаследовал приложение WinForms, написанное одним из моих предшественников. В этом приложении был процесс, который нужно было делать еженедельно, чтобы суммировать и обрабатывать миллионы записей. Помимо большого количества записей, база данных не была спроектирована должным образом, и в результате процесс занял более часа. Таким образом, пользователь застрял бы на своем компьютере в течение часа, наблюдая, как этот экран ничего не делает. У них не было возможности узнать, действительно ли приложение работало. Я добавил приведенный выше код в качестве временной меры, и конечный пользователь был чрезвычайно благодарен. Он очень ценил знание того, что приложение действительно работает, а не просто зависает.
Добавление приложения. DoEvents () увеличил время обработки с часа до часа и пяти минут или около того. Это было заметное замедление, НО пользователь был счастливее, потому что, хотя это занимало больше времени, он знал, что он делал.
Между прочим, это также сделало меня счастливее, потому что иногда, когда это занимало больше времени из-за необычно большого количества записей, пользователь завершал задачу программы и перезапускал ее, думая, что она заблокирована. Это неизбежно приведет ко мне приходится часами фиксировать данные.
В качестве последнего примечания я переписал приложение с нуля, включая перепроектирование базы данных, и тот же процесс теперь занимает 5 секунд. Я добавляю это не для того, чтобы похвастаться, а чтобы вы подумали о том, почему ваше приложение кажется заблокированным. Если вы можете подойти к задаче более эффективным образом и получить лучший дизайн, вы можете полностью избежать этого во многих случаях.