IsDisposed и Invoke. Что сделано неверно?
От: Аноним  
Дата: 09.07.11 11:06
Оценка:
Привет.

Мне при запуске моего WinForms приложения надо выполнить ряд длительных операций и результат вывести на форму программы. Чтоб ускорить запуск приложения эти длительные операции были вынесены в отдельны поток. Примерно так:

        private void MainForm_Shown(object sender, EventArgs e)
        {
            //skip code

            Thread myThread = new Thread(Execute);
            myThread.TrySetApartmentState(ApartmentState.STA);
            myThread.Start();

            //skip code
        }

        private void Execute()
        {
            //skip code

            if (!IsDisposed)
            {
                Invoke(new afterInitApplication(AfterInitApplication), outlookInfo, isPublicFolder);
            }
        }


При первом открытии формы я создаю новый поток, в этом потоке выполняю необходимые длительные операции пока открывается форма. После этого, если формочка не разрушена инвокаю метод AfterInitApplication в котором уже вывожу информацию на GUI.
Этот код работал длительное время на Windows XP без проблем. Но сейчас на Windows 7 x64 этот код иногда корится.
Я получаю эксепшин типа:
Message: Cannot access a disposed object.
Object name: 'MainForm'.

STACK TRACE:
at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
at MyApp.MainForm.Execute()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

Это происходит если запустить приложение и сразу его закрыть. Причём весьма нестабильно.
Мне непонятно что в этом коде неверно. Форма начинает разрушаться после if (!IsDisposed) и до вызова Invoke? Такое возможно? — какой же тогда смысл в проперти IsDisposed ?
Вопрос к гуру — что не так?

ps
Решение я придумал (ещё не проовал): вместо вызова Invoke я сделаю PostMessage — поставлю сообщение в очередь окна и там обработаю. Думаю, что это поможет.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.