.NET 3.5 C # Error con System.Timer System.ObjectDisposedException: no se puede acceder a un objeto desechado

En mi aplicación de servicio de Windows, uso mucho los temporizadores. Estoy usando solo System.Timers. Nunca antes había experimentado este problema, pero de repente recibí esta excepción:

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()

En mi método estoy deteniendo el temporizador y cambiando el intervalo del temporizador. Ese es el lugar donde obtuve la excepción.

He leído algo sobre este error, pero ¿aún es posible tener este error incluso en .NET 3.5?

¿Cómo lo soluciono? ¿Debo renovar el objeto del temporizador después de detenerlo y establecer el intervalo en un nuevo objeto? Estoy usando GC.KeepAlive (dataTimer);

Editar: Encontré algunas otras preguntas sobre este problema:

* Encontré un enlacehttp://www.kbalertz.com/kb_842793.aspx Básicamente, tan pronto como detiene un temporizador, el temporizador interno System.Threading.Timer está disponible para la recolección de elementos no utilizados, lo que a veces hace que el evento transcurrido no ocurra, o algunas veces provoca una excepción de referencia eliminada. Aunque no se describió en el artículo, mi solución fue crear un nuevo temporizador cada vez que se detuviera y volver a agregar los eventos transcurridos. No es eficiente pero fácil, y no es un problema para el procesador. Esto ha resuelto totalmente mi problema. Saludos para todos los que respondieron. *

Pero estoy confundido acerca de por qué el error sigue ahí, y necesito asegurarme de que volver a agregar el temporizador es una buena idea ...

Código que causó el error:

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

Se llamó a la función desde el evento SerialPortDataReceived:

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

El temporizador se detuvo antes de llamar al intervalo de cambio.

El temporizador es un campo privado de mi clase:

  private Timer asyncResponseTimer = new Timer();

EDITAR: ¡La aplicación se ha estado ejecutando durante varios meses seguidos y esta es la primera vez que recibo esta excepción!

Mi patrón de disposición:

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

Respuestas a la pregunta(3)

Su respuesta a la pregunta