首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF和WinForms调度员应该统一吗?

WPF和WinForms调度员应该统一吗?
EN

Stack Overflow用户
提问于 2016-02-02 15:05:36
回答 1查看 474关注 0票数 2

我有一个应用程序,它混合了WPF和WinForm控件,因为该项目早在WPF可用之前就已经启动了。不可能将所有控件更改为基于WPF的控件,这是因为控件的数量以及需要向后兼容其他构建进一步应用程序的控件。

现在,我偶尔会遇到重入问题,这会导致“集合被修改”异常,因为当我们调用WPF dispatcher消息时,由于其他挂起的WinForms消息,它将导致在发送WPF消息时出现在WinForms端的意外消息泵出。

典型的调用堆栈从WPF调用开始,但最终调用BeginInvoke WinForm消息,这会改变UI的状态。我可以通过事件处理程序来更改WPF集合,该集合此时正在枚举。

…。

代码语言:javascript
复制
   at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
   at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
   at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.Form.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.DispatcherOperation.Wait(TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherOperation operation, CancellationToken cancellationToken, TimeSpan timeout)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)

但是,实际的WPF仅导致这种情况的代码看起来是无辜的:

代码语言:javascript
复制
UIDispatcher.Current  (this is WPF Dispatcher) .Invoke(new Action<string, …>(delegate(string msg, …)
        {
            this.statusModel.AddToStatus(msg, …);
        }), new object[]
        {
            message,
            icon
        });

   at System.EventHandler`1.Invoke(Object sender, TEventArgs e)
….

这种行为有记录在案吗?因为我有WinForm和WPF代码,所以有一些基于WinForm的代码使用WinForm机制在uses (ISynchronizeInvoke of System.Windows.Forms.Control)中触发执行。

这基本上混合了WPF和WinForms发送的消息。什么是建议的解决办法,以摆脱这种混乱?如果我通过调用WPF Dispatcher调用来更改所有WinForms调用/BeginInvoke调用,那么我们就有一个通用的消息处理队列,而不是两个。还是有更好的方法?

更新1

混合WPF和WinForms的问题也可以在这里找到更详细的内容:

  • 意料之外的窗口消息泵送第2部分
  • 你能在等待锁的时候执行代码吗?
EN

回答 1

Stack Overflow用户

发布于 2016-02-02 15:35:24

如何嵌套调用,以便从您选择的消息泵中确定地触发所有调用?

就像这样:

代码语言:javascript
复制
yourWinFormsControl.Invoke((Action)(() =>
    {
        UIDispatcher.Current.Invoke(
            (Action)(() =>
            {
                this.statusModel.AddToStatus(xyz);
            }));
    }));

这将创建一个Action,它在WPF调度程序上执行调用,但将其推送给WinForms调度程序。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35156961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档