1

我正在开发一个在基于 Windows Mobile 5 的条形码扫描仪上运行的应用程序。有时我会遇到导致应用程序失败的跨线程异常。

该应用程序是用 C# 3.5 编写的,构建在 Motorola EMDK for .NET 之上,但也使用了Smart Device Framework的一部分。

在我的主窗体中,我有一个面板,我根据应用程序所处的上下文更改内容。所有视图共享一个公共接口 IContentView。

我还使用一些后台线程来监视设备当前是否正在充电(触发用户注销),并监视设备是否可以连接到服务器。

在面板上调用更改时,我从这里使用 John Skeets 构造,以确保在更改的控件上调用更改:

    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()

我在这里想念什么?我是否需要做其他事情才能将更改从线程正确编组到面板?

任何建议都受到高度赞赏。

4

1 回答 1

2

对我来说,添加content as UserControlControls.

检查IContentView content创建了哪个线程,我想不在主线程中,这可能是问题所在。

还请看这里:为什么你可以在 WinForms 中跨线程添加控件,而不是 WPF?

所以看起来这在 Windows 窗体中也是“禁止的”,但没有像框架代码那样严格检查。

所以解决方案是在主线程中创建所有 GUI 控件,可能也使用Invoke()

于 2015-02-27T09:24:48.093 回答