Исключение перекрестного потока при использовании Invoke()

Я разрабатываю приложение, работающее на сканере штрих-кода на базе Windows Mobile 5. Иногда я сталкиваюсь с перекрестным исключением, вызывающим сбой приложения.

Приложение написано на C# 3.5 и построено поверх Motorola EMDK для .NET, но также использует части Smart Device Framework.

В моей основной форме у меня есть панель, где я изменяю содержимое в зависимости от того, в каком контексте находится приложение. Все представления имеют общий интерфейс IContentView.

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

Я использую конструкцию Джона Скитса из здесь при вызове изменений на панели, чтобы обеспечить вызов изменений на меняется управление:

    public void ShowContent(IContentView content)
    {
        contentPanel.Invoke(() =>
            {
                contentPanel.Controls.Clear();
                contentPanel.Controls.Add(content as UserControl);
                contentPanel.Focus();
            });
    }

contentPanel является System.Windows.Forms.Panel.

Но я все еще получаю следующее исключение:

Control.Invoke must be used to interact with controls created on a separate thread.
   at Microsoft.AGL.Common.MISC.HandleAr(PAL_ERROR ar)
   at System.Windows.Forms.Control.get_Parent()
   at System.Windows.Forms.Control.ControlCollection.Add(Control value)
   at BarcodeScanner.MainView.MainForm.<>c__DisplayClass1e.<ShowContent>b__1d()
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean verifyAccess, StackCrawlMark& stackMark)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at System.Windows.Forms.Control.TASK.Invoke()
   at System.Windows.Forms.Control._InvokeAll()
   at System.Windows.Forms.Control.WnProc(WM wm, Int32 wParam, Int32 lParam)
   at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
   at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain)
   at System.Windows.Forms.Application.Run(Form fm)
   at BarcodeScanner.Program.Main()

Что мне здесь не хватает? Нужно ли мне делать что-то еще, чтобы правильно маршалировать изменения из потока в панель?

Любой совет высоко ценится.


person Moelgaard    schedule 27.02.2015    source источник
comment
stackoverflow.com/questions/1423446/thread-control-invoke   -  person SaneDeveloper    schedule 27.02.2015
comment
Ну, это явно не решило проблему. Вам необходимо опубликовать свой исходный код и трассировку стека исключений, то, что вы разместили здесь, не поможет нам вам помочь.   -  person Hans Passant    schedule 27.02.2015
comment
убедитесь, что IContentView, который кажется UserControl, также был создан в основном потоке.   -  person Marwie    schedule 27.02.2015


Ответы (1)


Мне кажется, что проблема возникает при добавлении content as UserControl к Controls.

Проверьте, в каком потоке IContentView content был создан, я полагаю, НЕ в основном потоке, что может быть проблемой.

Также посмотрите здесь: Почему вы можете пересекать добавлять элементы управления в WinForms, но не в WPF?

Таким образом, кажется, что это также «запрещено» в Windows Forms, но не так строго проверяется кодом фреймворка.

Таким образом, решение будет состоять в том, чтобы создать ВСЕ элементы управления графическим интерфейсом в основном потоке, возможно, также используя Invoke()

person Rainer Schaack    schedule 27.02.2015
comment
Большое Вам спасибо. Я думаю, ты здесь на месте. Некоторые из пользовательских элементов управления, устанавливаемых на панели (в основном те, которые активируются событиями), были созданы по мере необходимости. Я изменил его, чтобы все элементы управления создавались во время запуска приложения. Спасибо, что подтолкнули меня в правильном направлении. - person Moelgaard; 27.02.2015