Передовая практика задержек с уведомлением об обратном отсчете
-
26-10-2019 - |
Вопрос
Я склонен использовать следующий шаблон множество разных мест для временной задержки с событиями уведомления об обратном отсчете и возможности отмены:
CancellationToken ctoken = new CancellationToken();
for (int i = 0; i < 10; i++)
{
if (ctoken.IsCancellationRequested) break;
Thread.Sleep(1000);
if (ctoken.IsCancellationRequested) break;
if (Status != null) Status(this, new StatusEventArgs(i));
}
Что я хотел бы сделать, так это абстрагировать этот шаблон в свою собственную систему, которую я могу использовать для блокировки любого конкретного потока, пока не будет достигнут обратный отсчет. Есть ли какая -то лучшая практика для этого? Он должен обеспечить обратную связь с детальным статусом (предпочтительно я мог бы сказать ему, чтобы уведомлять меня каждую секунду, десятую секунды и т. Д.), И он должен поддерживать отмену (предпочтительно с лучшим ответом, чем каждая секунда). Я чувствую, что должен использовать новый CountdownEvent
функция в .net 4.0, или, возможно, используйте Monitor
Вместо того, чтобы просто спать, но я надеюсь на лучшее понимание здесь.
Решение
Первое, что вы должны сделать, это отделить идеи обратной связи и отмены. То есть у вас есть механизм обратной связи и механизм отмены, но они совсем не связаны. Если вы можете разделить эти две концепции, то с чем обращаться с ситуацией, а также будет работать лучше.
Вы хотите предоставить обратную связь с некоторым интервалом, что подразумевает таймер. И вместо того, чтобы опросить, чтобы увидеть, запрашивается ли отмена, вы можете подождать на ручке ожидания.
Что-то типа:
int i = 0;
using (System.Threading.Timer tmr = new System.Threading.Timer((s) =>
{
if (Status != null) Status(this, new StatusEventArgs(i));
++i;
}, null, 1000, 1000))
{
token.WaitHandle.WaitOne(TimeSpan.FromSeconds(10)));
}
Я предполагаю, что вы получаете CancellationToken
Откуда -то еще (т.е. он прошел, или вы определяете его, и другие могут повлиять на его состояние).