Лучшая практика для задержек потоков с уведомлением обратного отсчета
Я склонен использовать следующий шаблон для множества разных мест для временной задержки с событиями уведомлений обратного отсчета и возможностью отмены:
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
вместо того, чтобы просто спать, но я надеюсь на лучшее понимание здесь.
1 ответ
Первое, что вы должны сделать, это отделить идеи обратной связи и отмены. То есть у вас есть механизм обратной связи и механизм отмены, но они совсем не связаны. Если вы сможете разделить эти две концепции, то с ними будет легче иметь дело, а также они будут работать лучше.
Вы хотите предоставить обратную связь через некоторый интервал, который подразумевает таймер. И вместо того, чтобы узнать, запрашивается ли отмена, вы можете подождать на ручке ожидания.
Что-то вроде:
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
откуда-то еще (т. е. он передается внутрь, или вы определяете его, и другие могут влиять на его состояние).