Bug do .NET 3.5 C # com System.Timer System.ObjectDisposedException: Não é possível acessar um objeto descartado

No meu aplicativo de serviço do Windows, estou usando muito os timers. Estou usando apenas System.Timers. Eu nunca tive esse problema antes, mas de repente eu recebi essa exceção:

System.ObjectDisposedException: Cannot access a disposed object.
   at System.Threading.TimerBase.ChangeTimer(UInt32 dueTime, UInt32 period)
   at System.Threading.Timer.Change(Int32 dueTime, Int32 period)
   at System.Timers.Timer.UpdateTimer()
   at System.Timers.Timer.set_Interval(Double value)
   at MyApp.MySpace.MySpace2.MyClassWithTimer.MethodChangeTimerInterval()

No meu método, estou parando o cronômetro e alterando o intervalo do cronômetro. Esse é o lugar onde eu recebi a exceção.

Eu li algo sobre esse bug, mas ainda é passível de ter esse bug, mesmo no .NET 3.5?

Como faço para corrigir isso? Devo renovar o objeto de timer depois de parar e definir o intervalo para um novo objeto? Eu estou usando GC.KeepAlive (dataTimer);

Editar: Encontrei outras perguntas sobre esse problema:

* Encontrei um linkhttp://www.kbalertz.com/kb_842793.aspx Basicamente, assim que você interrompe um cronômetro, o System.Threading.Timer interno fica disponível para a Coleta de Lixo, às vezes fazendo com que o evento decorrido não ocorra ou às vezes causando uma exceção de referência descartada. Embora não tenha sido descrita no artigo, minha solução foi criar um novo cronômetro sempre que o cronômetro fosse parado e adicionar novamente os eventos decorridos. Não é eficiente, mas fácil, e não é um problema em termos de processador para mim. Isso resolveu totalmente o meu problema. Saúde para todos que responderam. *

Mas estou confuso sobre o motivo pelo qual o bug ainda está lá e preciso ter certeza de que adicionar novamente o timer é uma boa idéia ...

Código que causou o erro:

private void StartAsyncResponseTimer()
{
    switch (_lastRequestType)
    {
        case 1:
            asyncResponseTimer.Interval = 1000;
            break;
        case 2:
            asyncResponseTimer.Interval = 2000;
            break;
        case 3:
            asyncResponseTimer.Interval = 3000;
            break;
        default:
            asyncResponseTimer.Interval = 10000;
            break;
    }

    asyncResponseTimer.Start();
}

A função foi chamada do evento SerialPortDataReceived:

private void SerialPortDataReceived(object sender, EventArgs e)
{
       StartAsyncResponseTimer();
}

O temporizador foi parado antes de chamar o intervalo de alteração.

O temporizador é um campo privado da minha classe:

  private Timer asyncResponseTimer = new Timer();

EDIT: O aplicativo está sendo executado por vários meses seguidos e é a primeira vez que recebo essa exceção!

Meu padrão de descarte:

 public class SerialPortCommunication{

 ...

    private void SerialPortDataReceived(object sender, EventArgs e)
    {
        ReadResponse();

        StartAsyncResponseTimer();
    }

    //used to determine if is recieving response over
    private void StartAsyncResponseTimer()
    {
        switch (_lastRequestType)
        {
            case 1:
                asyncResponseTimer.Interval = 1000;
                break;
            case 2:
                asyncResponseTimer.Interval = 2000;
                break;
            case 3:
                asyncResponseTimer.Interval = 3000;
                break;
            default:
                asyncResponseTimer.Interval = 10000;
                break;
        }

        asyncResponseTimer.Start();
    }

    public virtual void Dispose()
    {

        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        if (!this._disposed)
        {
            if (disposing)
            {
                // Dispose managed resources.

            }

            // Dispose unmanaged resources.
            _disposed = true;

            Stop();

        }
    }

    ~SomeClass()
    {

        Dispose(false);
    }

    #endregion




    public void Stop()
    {
        _asyncResponseTimer.Stop();
        serialPortManager.ClosePort();
    }
}

questionAnswers(3)

yourAnswerToTheQuestion