É CancellationTokenSource.CancelAfter () com vazamento?

A liberação doPacote de segmentação assíncrona me levou a usarILSpy para dar uma olhada no quePadrão assíncrono baseado em tarefas (TAP) métodos de extensão foram fornecidos lá (alguns dos quais eu já implementei para uso no VS2010). Eu tropecei no.CancelAfter(TimeSpan) método paraCancellationTokenSource (que é como um método de extensão no Async Targeting Pack para .NET 4.0, mas é um método de instância no .NET 4.5) e achou que poderia ser uma boa maneira de implementar um tempo limite para várias operações que não possuem nativamente um tempo limite, mas suporta o cancelamento.

Mas olhando para a implementação no Async Targeting Pack, parece que se o associadoTask conclui ou é cancelado, o cronômetro continua em execução.

/// <summary>Cancels the <see cref="T:System.Threading.CancellationTokenSource" /> after the specified duration.</summary>
/// <param name="source">The CancellationTokenSource.</param>
/// <param name="dueTime">The due time in milliseconds for the source to be canceled.</param>
public static void CancelAfter(this CancellationTokenSource source, int dueTime)
{
    if (source == null)
    {
        throw new NullReferenceException();
    }
    if (dueTime < -1)
    {
        throw new ArgumentOutOfRangeException("dueTime");
    }
    Timer timer = new Timer(delegate(object self)
    {
        ((IDisposable)self).Dispose();
        try
        {
            source.Cancel();
        }
        catch (ObjectDisposedException)
        {
        }
    });
    timer.Change(dueTime, -1);
}

Digamos que eu use esse método para fornecer um tempo limite para uma operação baseada em TAP usada com freqüência e envolvê-la com um.CancelAfter(). Agora, digamos que o usuário forneça um valor de tempo limite de 5 minutos (300 segundos) e chame essa operação 100 vezes por segundo, todas concluídas com sucesso após alguns milissegundos. Após 300 segundos de 100 chamadas por segundo, 30.000 timers de execução teriam se acumulado em todas essas operações, mesmo que as tarefas tenham sido concluídas com sucesso há muito tempo. Todos eles acabariam por decorrer e executar o delegado acima, o que provavelmente lançaráObjectDisposedExceptionetc.

Isso não é um pouco um comportamento permeável e não escalonável? Quando implementei um tempo limite, useiTask/TaskEx.Delay(TimeSpan, CancellationToken) e quando a tarefa associada tiver terminado, cancelarei o.Delay() para que o timer seja interrompido e descartado (é um IDisposable afinal, e contém recursos não gerenciados). Esta limpeza é excessivamente zelosa? O custo de ter dezenas de milhares de timers funcionando simultaneamente (e possivelmente lançando dezenas de milhares de exceções capturadas posteriormente) é realmente irrelevante para o desempenho da aplicação média? É a sobrecarga e vazamento de.CancelAfter() quase sempre minúsculo em comparação com o trabalho real que está sendo feito, e geralmente deve ser desconsiderado?

questionAnswers(1)

yourAnswerToTheQuestion