2012-01-27 3 views
0

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

Теперь проблема заключается в том, что в это время, если пользователь снова нажмет F10, программа начнет делать то же самое, как только он выполнит первый процесс.

Как отключить захват ключей в определенный момент и включить его снова?

+1

Вы должны исправить настоящую проблему (временное становится постоянным) и поместить вычисления в поток apbackgrounf. Это должно быть очень просто с помощью параллельной библиотеки задач: http://msdn.microsoft.com/en-us/library/dd537609.aspx – Jason

+1

Действительно ли дорого переместить вычисления в BackgroundWorker и просто отключить форму до завершения обратного вызова завершения поднял? – dmay

ответ

2

Программа не «захватывает ключ», она поставлена ​​в очередь операционной системой, потому что ваш основной пользовательский интерфейс занят вашими вычислениями и в то время ничего не обрабатывает. Единственное, что я мог подумать о том, что вы можете сделать, это проверить, что прошло определенное время после последнего запуска, прежде чем разрешить другой запуск. Уродливое взломать мое скромное мнение.

Но, да, вот почему вы должны использовать фоновые работники или потоки. Использование BackgroundWorker намного проще, чем может показаться в начале.

+0

Именно по этим причинам создается Threading. Сделайте некоторые исследования и устраните проблему в ядре. В противном случае вы получите стек заглушек, который должен быть исправлен. В «Управление проектами» это называется «Стратегия бесконечного дефекта». – Oybek

+0

Использование таймера никогда не является хорошим вариантом - что происходит, если ваш процессор находится под нагрузкой, а вычисления занимают дольше, чем ваш таймер, - теперь ваша спина к квадрату. Скажем, вы компенсируете этот сценарий и увеличиваете свой таймер, ваш процессор находится под нормальной нагрузкой, и теперь ваши расчеты завершены, и теперь вы ожидаете, что ваш таймер освободит пользовательский интерфейс. Нехорошее решение с любой точки зрения. – Bertie

+0

Где я рекомендую использовать таймер? Я бы просто сохранил текущие микросекунды в переменной _lastRunMicroSeconds сразу после завершения моего долговременного процесса и не разрешить последующий прогон до currentMicroSeconds> (_lastRunMicroSeconds + bufferMicroSeconds), где размер буфера должен быть определен. Я также не сказал, что это хорошее решение. :) – Till

0

В идеале вы должны использовать BackgroundWorker здесь, но, как вы сказали

Я не хочу, чтобы изменить программу способ работает в данный момент).

Так что я не пойду на этот путь.

Что вы можете сделать, это обнаружить, когда F-10 впервые установил значение bool в true и в следующий раз, когда вы обнаруживаете f-10, проверьте, является ли bool уже истинным или нет. Если это уже верно, не запускайте тяжелую операцию снова, просто пропустите код.

В конце тяжелой обработки снова установите bool в false.

+0

Это не удастся, потому что тяжелая работа над ui-thread будет завершена, и bool вернется в true, когда событие нажатия клавиши достигнет программы. – Till

+0

Я не думаю, что bool что-нибудь исправит, так как второй тяжелый процесс начинается, как только заканчивается первый. – ken2k

0

Я согласен с Джейсоном в целом - хаки и временные исправления имеют неприятную привычку становиться «функциями» программы.

Однако, чтобы ответить на ваш вопрос, я предлагаю иметь в вашей программе флаг отключения, который отключает требуемые функции во время выполнения ваших вычислений. Затем вы можете ввести в обработчик события проверку флага:

public bool DisableFlag { get; set; } 

public void MyKeyEventHandler(object sender, EventArgs e) 
{ 
    if (DisableFlag) 
    { 
     return; 
    } 

    // Do stuff 
} 

Надеюсь, что это поможет!
Cheers,
Chris.

EDIT:

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

myControl =- MyKeyEventHandler; 

, а затем

myControl =+ MyKeyEventHandler; 

когда расчеты закончены. Таким образом, никакие события не поставлены в очередь, и вы избегаете проблемы, описанной Кеном !!

+0

Я не думаю, что он что-то исправит, поскольку сообщения KeyPress будут обработаны после завершения тяжелого процесса. Поскольку вам нужно будет включить свой флаг после завершения процесса, проблема останется. – ken2k

Смежные вопросы