У меня есть ApplicationContext
с Form
. Различные асинхронные потоки связи и синхронизации могут время от времени перезапускать приложение, однако, прежде чем я смогу перезапустить, мне нужно вручную утилизировать MyApplicationContext
, которому необходимо бесплатно освободить ресурсы, которые понадобятся , когда начнется новый процесс.Безопасный вызов в форме. Метод Dispose()
Кажется, что только вызов Application.Restart()
не избавляет от ресурсов достаточно быстро в этом случае.
В вызове MyApplicationContext.Dispose()
последующий вызов base.Dispose(disposing)
в конечном итоге вызывает метод Form.Dispose()
, и потому, что это может происходить из различных нитей, я видел исключение операции кросс-нить происходит.
/// MyApplicationContext.requestRestart()
private void requestRestart()
{
this.Dispose(); // dispose of applicationcontext
Application.Restart();
}
приводит к ...
/// MyApplicationContext.Dispose(bool)
protected override void Dispose(bool disposing)
{
/// dispose stuff
base.Dispose(disposing);
}
приводит к ...
/// MainForm.Dispose(bool)
protected override void Dispose(bool disposing)
{
/// dispose stuff
base.Dispose(disposing);
}
который может быть вызван из любого потока.
Безопасно ли для Invoke
переопределяемый обработчик на Form
пользовательских интерфейсов?
protected override void Dispose(bool disposing)
{
if (this.InvokeRequired)
{
this.Invoke(new Action(() => Dispose(disposing)));
}
else
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
}
Действительно, я был * ушел * вместе с ним.Я думаю, что будет достаточно легко переместить мой метод 'requestRestart' в класс' Form', так что если требуется вызов перекрестного потока, это делается в нижней части стека вызовов. Но в этом случае невозможно гарантировать, что поток, инициирующий запрос на перезагрузку, будет потоком пользовательского интерфейса «Form'», например, когда придет сеть IO. – khargoosh
Вы можете инициировать запрос на перезагрузку в любом месте, если вы убедитесь, что вы переместились в поток пользовательского интерфейса, прежде чем на самом деле _handling_ очистка, которая предшествует запросу на перезапуск. Даже там вам может показаться полезным/желательно использовать 'SynchronizationContext' вместо экземпляра' Form', так как предположительно, что экземпляр 'Form' будет удаляться как часть очистки (т. Е. Вы все еще имеете проблему вызова' Invoke() 'на объект, который будет удален до того, как метод Invoke() будет возвращен). –
Я принял ваш хороший совет и использую 'SynchronizationContext' из основной формы. Спасибо, Питер. Я чувствую себя намного лучше о том, как это происходит сейчас. – khargoosh