Cannot access a disposed object

В проекте VB.NET WinForms я получаю исключение

Невозможно получить доступ к удаленному объекту

при закрытии формы. Это происходит очень редко, и я не могу воссоздать его по требованию. Трассировка стека выглядит следующим образом:

DbiSchedule – это управление расписанием от Dbi-tech. В форме есть таймер, который обновляет расписание на экране каждые несколько минут.

Любые идеи, что вызывает исключение и как я мог бы исправить это? или даже просто восстановить его по требованию?

Хей! Спасибо за ответы на все вопросы. Мы останавливаем Timer для события FormClosing и проверяем свойство IsDisposed в компоненте расписания, прежде чем использовать его в событии Timer Tick, но это не помогает.

Это действительно раздражающая проблема, потому что, если кто-то придумал решение, которое сработало, я бы не смог подтвердить решение, потому что я не могу воссоздать проблему вручную.

Попробуйте проверить свойство IsDisposed до доступа к элементу управления. Вы также можете проверить его на событии FormClosing, если вы используете событие FormClosed.

Мы останавливаем таймер на FormClosing, и мы проверяем Свойство IsDisposed в расписании компонента перед его использованием в таймере Tick, но это не помогает.

Вызов GC.Collect перед проверкой IsDisposed может помочь, но будьте осторожны с этим. Прочитайте эту статью Рико Мариани " Когда вызывать GC.Collect()".

Это похоже на проблему с потоками.
Гипотеза: Возможно, у вас есть основной поток и поток таймера, обращающиеся к этому элементу управления. Основной поток завершает работу, вызывая Control.Dispose(), чтобы указать, что я закончил с этим элементом управления, и больше не буду вызывать этого. Однако поток таймера все еще активен – переключение контекста на этот поток, где он может вызывать методы в том же элементе управления. Теперь контроль говорит, что я Уничтожен (уже отказался от моих ресурсов), и я больше не буду работать. Исключение ObjectDisposed.

Как решить эту проблему: перед тем, как вызывать методы/свойства элемента управления, выполните проверку с помощью

ИЛИ остановите поток таймера ДО утилизации объекта.

мы проверяем свойство IsDisposed на компонент расписания перед его использованием в событии Timer Tick, но это не помощь.

Если я понимаю, что трассировка стека, это не ваш таймер, который является проблемой, он один в самом элементе управления – это могут быть те, кто не очищается должным образом.

Вы явно вызываете Dispose на свой контроль?

Остановка таймера не означает, что он не будет вызываться снова, в зависимости от того, когда вы остановите таймер, timer_tick все еще может быть поставлен в очередь в контуре сообщения для формы. Что произойдет, так это то, что вы получите еще один тик, которого вы, возможно, не ожидаете. Что вы можете сделать, так это в вашем timer_tick, перед запуском метода Timer_Tick проверьте свойство Enabled вашего таймера.

Читайте также:  Hp pavilion g6 1002er

У меня была та же проблема, и я решил ее с помощью логического флага, который устанавливается при закрытии формы (System.Timers.Timer не имеет свойства IsDisposed). Везде на форме я запускал таймер, он проверял этот флаг. Если он был установлен, то не запускайте таймер. Вот причина:

Причина:

Я останавливался и избавлялся от таймера в закрытии формы. Я запускал таймер в событии Timer_Elapsed(). Если бы я должен был закрыть форму в середине события Timer_Elapsed(), таймер был бы немедленно уничтожен событием Form_Closing(). Это произойдет до того, как событие Timer_Elapsed() завершится, и, что более важно, до того, как оно попадет в следующую строку кода:

Как только эта строка будет выполнена, ObjectDisposedException() будет выдан с упомянутой вами ошибкой.

Решение:

Здесь таймер истекшего события:

Интересно знать, что даже при попытке запуска таймера выдается исключение ObjectDisposedException, таймер все равно запускается, вызывая его запуск даже при закрытии формы (поток останавливается только при закрытии приложения).

Определение

Исключение, которое выбрасывается при выполнении операции над удаленным объектом. The exception that is thrown when an operation is performed on a disposed object.

Примеры

В следующем примере показана ошибка, вызывающая ObjectDisposedException возникновение исключения. The following example demonstrates an error that causes the ObjectDisposedException exception to be thrown.

Этот код выводит следующие результаты: This code produces the following output:

Комментарии

Исключение возникает при попытке получить доступ к члену объекта, IDisposable реализующего интерфейс, и этот объект был удален. ObjectDisposedException An ObjectDisposedException is thrown when you try to access a member of an object that implements the IDisposable interface, and that object has been disposed. Как правило, это исключение вызывается одним из следующих условий: Typically, this exception is caused by one of the following conditions:

Вы вызвали Dispose метод объекта и пытаетесь получить доступ к члену экземпляра, который получает или задает состояние объекта. You’ve called an object’s Dispose method, and you’re trying to access an instance member that gets or sets the object’s state. В следующем примере показано ObjectDisposedException , что вызывается при попытке сбросить частоту уведомлений таймера после Timer.Dispose вызова метода. The following example illustrates the ObjectDisposedException that is thrown when you try to reset the frequency of timer notifications after you call the Timer.Dispose method.

Вы вызвали Close метод объекта и пытаетесь получить доступ к члену экземпляра, который получает или задает состояние объекта. You’ve called an object’s Close method, and you’re trying to access an instance member that gets or sets the object’s state. Часто метод предоставляет открытую реализацию IDisposable.Dispose метода типа. Close Often, the Close method provides a type’s public implementation of the IDisposable.Dispose method.

Dispose Метод объекта был вызван несколько раз. You’ve called an object’s Dispose method multiple times. Как правило, это не создает исключение. Typically, this doesn’t throw an exception. Однако в зависимости от реализации IDisposable.Disposeтипа он может не допускать несколько Dispose вызовов. However, depending on how a type implements IDisposable.Dispose, it may not allow multiple calls to Dispose .

Читайте также:  Программа для создания слайд фильма

В большинстве случаев это исключение возникает при возникновении ошибки разработчика. In most cases, this exception results from developer error. Вместо обработки ошибки в try / catch блоке следует исправить ошибку, обычно путем повторного создания экземпляра объекта. Instead of handling the error in a try / catch block, you should correct the error, typically by reinstantiating the object.

Конструкторы

Инициализирует новый экземпляр класса ObjectDisposedException с сериализованными данными. Initializes a new instance of the ObjectDisposedException class with serialized data.

Инициализирует новый экземпляр класса ObjectDisposedException строкой, содержащей имя удаленного объекта. Initializes a new instance of the ObjectDisposedException class with a string containing the name of the disposed object.

Инициализирует новый экземпляр класса ObjectDisposedException указанным сообщением об ошибке и ссылкой на внутреннее исключение, вызвавшее данное исключение. Initializes a new instance of the ObjectDisposedException class with a specified error message and a reference to the inner exception that is the cause of this exception.

Инициализирует новый экземпляр класса ObjectDisposedException указанными именем объекта и сообщением. Initializes a new instance of the ObjectDisposedException class with the specified object name and message.

Свойства

Возвращает коллекцию пар ключ/значение, предоставляющие дополнительные сведения об исключении, определяемые пользователем. Gets a collection of key/value pairs that provide additional user-defined information about the exception.

(Унаследовано от Exception)

HelpLink

Получает или задает ссылку на файл справки, связанный с этим исключением. Gets or sets a link to the help file associated with this exception.

(Унаследовано от Exception)

HResult

Возвращает или задает HRESULT — кодированное числовое значение, присвоенное определенному исключению. Gets or sets HRESULT, a coded numerical value that is assigned to a specific exception.

(Унаследовано от Exception)

InnerException

Возвращает экземпляр класса Exception, который вызвал текущее исключение. Gets the Exception instance that caused the current exception.

(Унаследовано от Exception)

Message

Возвращает сообщение с описанием ошибки. Gets the message that describes the error.

Возвращает имя удаленного объекта. Gets the name of the disposed object.

Возвращает или задает имя приложения или объекта, вызывавшего ошибку. Gets or sets the name of the application or the object that causes the error.

(Унаследовано от Exception)

StackTrace

Получает строковое представление непосредственных кадров в стеке вызова. Gets a string representation of the immediate frames on the call stack.

(Унаследовано от Exception)

TargetSite

Возвращает метод, создавший текущее исключение. Gets the method that throws the current exception.

(Унаследовано от Exception)

Методы

Определяет, равен ли заданный объект текущему объекту. Determines whether the specified object is equal to the current object.

Читайте также:  Хром не открывает страницы андроид

(Унаследовано от Object)

GetBaseException()

При переопределении в производном классе возвращает исключение Exception, которое является корневой причиной одного или нескольких последующих исключений. When overridden in a derived class, returns the Exception that is the root cause of one or more subsequent exceptions.

(Унаследовано от Exception)

GetHashCode()

Служит хэш-функцией по умолчанию. Serves as the default hash function.

(Унаследовано от Object)

GetObjectData(SerializationInfo, StreamingContext)

Извлекает объект SerializationInfo с именем параметра и дополнительной информацией об исключении. Retrieves the SerializationInfo object with the parameter name and additional exception information.

Возвращает тип среды выполнения текущего экземпляра. Gets the runtime type of the current instance.

(Унаследовано от Exception)

MemberwiseClone()

Создает неполную копию текущего объекта Object. Creates a shallow copy of the current Object.

(Унаследовано от Object)

ToString()

Создает и возвращает строковое представление текущего исключения. Creates and returns a string representation of the current exception.

(Унаследовано от Exception)

События

Возникает, когда исключение сериализовано для создания объекта состояния исключения, содержащего сериализованные данные об исключении. Occurs when an exception is serialized to create an exception state object that contains serialized data about the exception.

Cannot access a disposed object

Anyone know why I would get this error "Cannot access a disposed object" on this line of code

Hit start over then either accept / reject / or close the form — seems to happen when closing the form

the error happens when you bring the form up again

form2

3 Answers 3

Your form is disposed by the time invoke() message is processed by the message loop. I donot think so there is a way to avoid it. You can put a check e.g

But that may not work sometime as the invoke is posted to UI thread and by the time it is process form may already be disposed and you will still get that exception. You have to fix your program in a way to avoid this situation by making sure invoke is not posted on a disposed or disposing form. This is a fatal error and your program will exit after this. I think suppressing it via try<>catch<> will not work as framework already start to unload when catch block is executed.

You can fix the problem in two ways. 1. Just drop a timer component from toolbox i.e. System.Windows.Forms.Timer and use that. Designer will automatically add it to component collection and dispose it before form is disposed. 2. Manually over OnDispose(bool disposing) in your form and perform

So now your timer is dispose before your form so no subsequent invoke() will be posted to your form after its disposed.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock detector