Задержка, после которой пользовательский интерфейс снова начинает реагировать, является сильным признаком основной причины проблемы. Вы видите, как Windows лечит себя, замечая, что обратный вызов не отвечает. Это автоматически отключает крючок.
Жесткое требование, которое вы, вероятно, нарушаете, заключается в том, что вызов SetWindowsHookEx () должен выполняться из потока, который прокачивает цикл сообщений. Так что Windows может взломать нажатие клавиши и вызвать обратный вызов. Это прекрасно работает, когда вы вызываете метод Start () одним нажатием кнопки, событие Click запускается в потоке пользовательского интерфейса вашей программы.
Но, вероятно, не , когда вы делаете этот вызов из сетевого события. Они имеют тенденцию работать в потоке потоков. Из вашего фрагмента не ясно, вы не опубликовали код. Общее решение такой проблемы - использование Control.BeginInvoke () для перенаправления вызова из рабочего потока в поток пользовательского интерфейса. Хорошее описание вы найдете в статье библиотеки MSDN, а также множество ответов здесь на stackoverflow.com
Кстати, оригинальный код был поврежден из-за изменения поведения в .NET 4 версии CLR. Он больше не подделывает родной модуль для сборок. Обходной путь достаточно хорош, ему нужен только действительный дескриптор модуля. Фактический не имеет значения, поскольку это не глобальный хук.