Я использую System.Threading.Timer
в моей службе Windows и блокирую метод обратного вызова с использованием Monitor.TryEnter
, поэтому он не реентерабелен. Внутри обратного вызова я перебираю некоторые объекты базы данных (объекты Linq to SQL) и выполняю некоторые задачи ввода-вывода. На каждой итерации цикла я меняю некоторые свойства сущности, чтобы отметить ее как обработанную. После выхода цикла я вызываю SubmitChanges
в datacontext, который сохраняет изменения в базе данных. Возникает следующая проблема: если служба останавливается во время выполнения обратного вызова, некоторые из задач ввода-вывода могут быть уже выполнены, но записи не были отмечены как обработанные в базе данных (например, SubmitChanges еще не вызывается) - очевидно, не то, что я хочу. Каким-то образом мне нужно связаться с потоком рабочего обратного вызова, которое событие OnStop уволило, чтобы позволить ему отправлять изменения и обертывать вещи. Как лучше всего это сделать?Изящно остановить поток обратного вызова таймера
ответ
1-й решает, завершите ли вы выполнение задач обратного вызова или отложите их. Поэтому, если вы решите закончить задачи, вы выполните обратный вызов до конца. Время должно быть отменено в OnStop уже. Если вы будете ехать со вторым вариантом (откатом) ваш код будет выглядеть примерно так:
bool shouldAbort=false;
TimerProc()
{
Step1();
if (shouldAbort)
{
UndoStep1();
return;
}
Step2();
if (shouldAbort)
{
UndoStep2();
UndoStep1(); // or vice versa, depending on your operations
return;
}
// ...
}
в OnStop()
timer.Stop(); // don't worry here - your TimerProc() WILL finish
shouldAbort=true;
, если у вас есть проблемы с TimerProc(), которые не выполняются, используйте AutoResetEvent и WaitOne() после убийства таймера и Set() событие в конце TimerProc() –
Спасибо за предложение. * * * остановить таймер в OnStop: timer.Change (Timeout.Infinite, 0) - использовать таймер из пространства имен Threading. Но я также хочу сигнализировать обратный вызов поток, который нужно быстро завершить (без отката). Возможно, сценарий, который делает необходимость более очевидным, - это событие выключения. – Antony
Есть два Антониса: тот, кто хочет, чтобы задача быстро завершилась, а другая, которая не хочет долгое время i/o задачи, которые нужно насильственно убить. Надо отказаться, давайте дать им некоторое время, чтобы решить :) –
Вы можете посмотреть на использование Task Parallel Library. Прочтите страницу Task Cancellation. Это даст вам возможность создать рабочие потоки, которые могут быть аккуратно очищены в ответ на отмену, если я правильно понял ваши потребности.
Выглядит очень интересно, но, к сожалению, я все еще использую Framework 3.5 :( – Antony
- 1. Как изящно остановить звуковое устройство python изнутри обратного вызова
- 2. это правильный способ «остановить» поток изящно?
- 3. Остановить распространение обратного вызова
- 4. python eve изящно выходит из обратного вызова
- 5. Нежелательная прекращение Thread созданного таймера обратного вызова
- 6. ntwitter: остановить прослушивание на поток событий после X обратного вызова
- 7. Как остановить/запустить или перезапустить поток таймера
- 8. passportjs обратного вызова код поток
- 9. Остановить методы обратного вызова iAd
- 10. Контекст обратного вызова таймера программного обеспечения
- 11. Thread.Sleep вызывает задержку обратного вызова таймера
- 12. Long precedure в функции обратного вызова таймера
- 13. Выполнение обратного вызова таймера в c
- 14. Остановить SqlDependency изящно
- 15. Как остановить поток изящно с помощью Cntrl + C в Python
- 16. Считываемый поток и функция обратного вызова
- 17. поток для функции обратного вызова в timeout_add
- 18. Остановить распространение в fullcalendar выбора обратного вызова
- 19. Как остановить срабатывание обратного вызова события?
- 20. MATLAB: Как ждать остановки таймера внутри обратного вызова GUI?
- 21. Ошибка таймера обратного отсчета PHP
- 22. Как остановить подсчет количества кликов при остановке таймера обратного отсчета?
- 23. Как прекратить java-поток изящно?
- 24. Как остановить процесс Java изящно?
- 25. Как разрешить поток, который блокирует recv() изящно?
- 26. Как изящно остановить воспроизведение видео html5
- 27. Ошибка таймера обратного отсчета
- 28. Уведомление таймера обратного отсчета
- 29. Сброс таймера обратного отсчета
- 30. Использование таймера обратного отсчета
Я предположил, что ваша проблема в том, что, убивая таймер, который вы будете убить выполнение функции обратного вызова таймера, правильно ли это? –
Не совсем. Я должен быть более ясным; Я понимаю, что остановка таймера просто прекращает его снова стрелять, но не убивает метод обратного вызова. Однако некоторые из задач ввода-вывода могут быть длительными - может быть, несколько минут. Я не хочу, чтобы пользователь (или система) принудительно прервал процесс, если он слишком долго. Я бы предпочел, чтобы это обслуживание закончилось изящно. – Antony
Ну, у службы управления есть метод RequestMoreTime() или что-то в этом роде (я говорю из памяти), с помощью которого вы можете продлить время своего обслуживания и все еще не быть повешенным для SCM. –