.net - instalar - windows forms c# visual studio 2017
No se puede acceder a un objeto eliminado-¿Cómo arreglarlo? (11)
comprobamos la propiedad IsDisposed en el componente del cronograma antes de usarla en el evento Tick Timer, pero no ayuda.
Si entiendo ese rastro de la pila, no es su temporizador el problema, es uno en el control en sí mismo; podrían ser ellos quienes no están limpiando adecuadamente.
¿Llamas explícitamente a Dispose sobre su control?
En un proyecto WinForms de VB.NET, recibo una excepción
No se puede acceder a un objeto eliminado
al cerrar un formulario. Ocurre muy raramente y no puedo recrearlo bajo demanda. El seguimiento de la pila se ve así:
Cannot access a disposed object. Object name: ''dbiSchedule''.
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.Control.PointToScreen(Point p)
at Dbi.WinControl.Schedule.dbiSchedule.a(Boolean A_0)
at Dbi.WinControl.Schedule.dbiSchedule.a(Object A_0, EventArgs A_1)
at System.Windows.Forms.Timer.OnTick(EventArgs e)
at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
El dbiSchedule es un control de programación de Dbi-tech. Hay un temporizador en el formulario que actualiza el programa en la pantalla cada pocos minutos.
¿Alguna idea de lo que está causando la excepción y cómo podría solucionarlo? o incluso solo poder recrearlo bajo demanda?
Hej! Gracias por todas las respuestas. Detenimos el temporizador en el evento FormClosing y comprobamos la propiedad IsDisposed en el componente del cronograma antes de usarlo en el evento Ticker Tick, pero no ayuda.
Es un problema realmente molesto porque si alguien presentara una solución que funcionara, no podría confirmar la solución porque no puedo volver a crear el problema manualmente.
¿Estás seguro de que el temporizador no está sobreviviendo al ''dbiSchedule'' de alguna manera y disparando después de que el ''dbiSchedule'' ha sido eliminado?
Si ese es el caso, es posible que puedas recrearlo de manera más consistente si el temporizador dispara más rápido, lo que aumenta las posibilidades de que cierres el Formulario justo cuando el temporizador está disparando.
Al observar el seguimiento de la pila de errores, parece que su temporizador aún está activo. Intente cancelar el temporizador al cerrar el formulario ( es decir, en el método OnClose () del formulario). Esta parece la solución más limpia.
Detener el temporizador no significa que no se volverá a llamar, dependiendo de cuándo se detiene el temporizador, el temporizador_tick aún se puede poner en la cola del mensaje para el formulario. Lo que sucederá es que obtendrá un tic más que puede que no esté esperando. Lo que puede hacer es en su timer_tick, verifique la propiedad Enabled de su temporizador antes de ejecutar el método Timer_Tick.
Intente verificar la propiedad IsDisposed antes de acceder al control. También puede verificarlo en el evento FormClosing , suponiendo que está utilizando el evento FormClosed.
Detenimos el temporizador en el evento FormClosing y comprobamos la propiedad IsDisposed en el componente del cronograma antes de usarlo en el evento Ticker Tick, pero no ayuda.
Llamar a GC.Collection antes de verificar IsDisposed puede ayudar, pero tenga cuidado con esto. Lea este artículo de Rico Mariani " Cuándo llamar a GC.Collect () ".
Mi solución fue poner a prueba la captura, y está funcionando bien
tratar {
this.Invoke (nuevo EventHandler (DoUpdate)); }
captura { }
Otro lugar donde puede detener el temporizador es el evento FormClosing : esto sucede antes de que el formulario esté realmente cerrado, por lo que es un buen lugar para detener las cosas antes de que puedan acceder a los recursos no disponibles.
Parece un problema de enhebrado.
Hipótesis : quizás tengas un hilo principal y un hilo de temporizador accediendo a este control. El hilo principal se apaga, llamando Control.Dispose () para indicar que he terminado con este control y no haré más llamadas a esto. Sin embargo, el hilo del temporizador todavía está activo: un cambio de contexto a ese hilo, donde puede llamar a métodos en el mismo control. Ahora el control dice que estoy Dispuesto (ya cedí mis recursos) y ya no trabajaré más. ObjectDisposed exception.
Cómo resolver esto : en el hilo del temporizador, antes de llamar a los métodos / propiedades en el control, verifique con
if ControlObject.IsDisposed then return; // or do whatever - but don''t call control methods
O pare el hilo del temporizador ANTES de tirar el objeto.
Si esto sucede esporádicamente, supongo que tiene algo que ver con el temporizador.
Supongo (y esto es solo una suposición, ya que no tengo acceso a tu código) que el temporizador se dispara mientras se cierra el formulario. El objeto dbiSchedule ha sido eliminado, pero el temporizador de alguna manera aún trata de llamarlo. Esto no debería suceder, porque si el temporizador tiene una referencia al objeto de programación, el recolector de basura debería ver esto y no deshacerse de él.
Esto me lleva a preguntar: ¿estás llamando a Dispose () en el objeto del cronograma de forma manual? Si es así, ¿lo estás haciendo antes de tirar el temporizador? Asegúrese de liberar todas las referencias al objeto de programación antes de desecharlo (es decir, disponer del temporizador de antemano).
Ahora me doy cuenta de que han pasado unos meses entre el momento en que publicaste esto y el momento en que estoy respondiendo, por lo que espero que hayas resuelto este problema. Escribo esto para el beneficio de otros que pueden llegar más tarde con un problema similar.
Espero que esto ayude.
Tuve el mismo problema y lo resolví usando un indicador booleano que se establece cuando el formulario se está cerrando (el System.Timers.Timer no tiene una propiedad IsDisposed). En todas partes en el formulario que estaba iniciando el cronómetro, hice que verificara esta bandera. Si se configuró, entonces no inicie el temporizador. Esta es la razón:
La razón:
Estaba deteniendo y desechando el temporizador en el evento de cierre de formulario. Estaba comenzando el temporizador en el evento Timer_Elapsed (). Si tuviera que cerrar el formulario en el medio del evento Timer_Elapsed (), el evento Form_Closing () eliminaría inmediatamente el temporizador. Esto sucedería antes de que termine el evento Timer_Elapsed () y, lo que es más importante, antes de llegar a esta línea de código:
_timer.Start()
Tan pronto como se ejecutó esa línea, se lanzaría una ObjectDisposedException () con el error que mencionó.
La solución:
Private Sub myForm_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
'' set the form closing flag so the timer doesn''t fire even after the form is closed.
_formIsClosing = True
_timer.Stop()
_timer.Dispose()
End Sub
Aquí está el evento del temporizador transcurrido:
Private Sub Timer_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Handles _timer.Elapsed
'' Don''t want the timer stepping on itself (ie. the time interval elapses before the first call is done processing)
_timer.Stop()
'' do work here
'' Only start the timer if the form is open. Without this check, the timer will run even if the form is closed.
If Not _formIsClosing Then
_timer.Interval = _refreshInterval
_timer.Start() '' ObjectDisposedException() is thrown here unless you check the _formIsClosing flag.
End If
End Sub
Es interesante saber que, aunque arrojaría ObjectDisposedException al intentar iniciar el temporizador, el temporizador seguiría activándose, causando que se ejecutara incluso cuando el formulario estuviera cerrado (el hilo solo se detendría cuando se cerrara la aplicación).
porque la carpeta de la solución estaba dentro de la carpeta OneDrive.
Si mueve las carpetas de solución fuera de la carpeta de una unidad, los errores desaparecerán.
mejor