Pergunta

I tend to use the following pattern a lot of different places for a timed delay with countdown notification events, and the ability to cancel:

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));
}

What I would like to do is abstract this pattern into its own system I can use to block any particular thread until a countdown is reached. Is there some sort of best practice for this? It must provide granular status feedback (preferably I could tell it to notify me every second, tenth of a second, etc.), and it must support cancellation (preferably with better response than each second). I feel I should be using the new CountdownEvent feature in .NET 4.0, or maybe use a Monitor instead of just sleeping, but I'm hoping for some better insight here.

Foi útil?

Solução

The first thing you should do is separate the ideas of feedback and cancellation. That is, you have a feedback mechanism and a cancellation mechanism, but they are not at all related. If you can separate those two concepts, then things get easier to deal with and also will perform better.

You want to provide feedback at some interval, which implies a timer. And rather than polling to see if cancellation is requested, you can wait on the wait handle.

Something like:

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)));
}

I assume that you're getting the CancellationToken from somewhere else (i.e. it's passed in, or you define it and others can affect its state).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top