首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >以threadsafe方式创建新窗口

以threadsafe方式创建新窗口
EN

Stack Overflow用户
提问于 2012-07-30 22:36:35
回答 3查看 185关注 0票数 1

我使用signalR将消息向上推送到服务器,然后向下推送到特定的客户端。

当我发送消息时,从我的signalR服务器向接收客户端发送一个ReceiveMessage函数调用,该函数映射到我的应用程序中的一个静态类函数。然后,静态类尝试执行new Chat() (我的消息传递窗口类),以便在接收端打开一个消息窗口。

这会抛出calling thread must be STA, because many UI components require this.

我以前在简单的表单元素(如更改文本框)上使用过委托,但我不知道如何在这种情况下应用它。当我读到Invoke时,它是在某种形式的表单对象上调用的,这在我的情况下是不存在的?

如何通过静态类函数调用创建和显示窗体的新实例

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-07-30 22:44:40

使用当前GUI的线程调度程序。然后调用invoke。Par示例:

代码语言:javascript
运行
复制
Application.Current.Dispatcher.Invoke(() => { 
      var win = new Window();
      win.show(); 
});
票数 5
EN

Stack Overflow用户

发布于 2012-07-30 22:41:43

最简单的:使用App.MainWindow.Dispatcher在GUI线程上执行创建:

代码语言:javascript
运行
复制
App.MainWindow.Dispatcher.BeginInvoke((Action)(() => { new Chat(); }));

更难:创建一个新的STA线程,并在其上创建新窗口。

后一种选择比较困难,因为您将拥有多个GUI线程,并且需要确保跟踪操作,以便在每种情况下都使用正确的线程。除非您有特定的原因需要使用多个GUI线程,否则请坚持使用简单的选项。

票数 2
EN

Stack Overflow用户

发布于 2012-07-30 22:49:04

您必须在UI线程中调用代码。要做到这一点,您需要引用同步上下文。假设您从UI线程调用了以下代码:

代码语言:javascript
运行
复制
SynchronizationContext syncContext = SynchronizationContext.Current;

因此,您获得了对上下文的引用。

然后,在回调方法中(在后台线程(而不是UI)中接收到消息后),您可以执行以下操作:

代码语言:javascript
运行
复制
syncContext.Post((state) =>
                {
                    Window w = new Window(); 

                }, ...);

lambda表达式中的代码代表UI线程执行。据我所知,这是"Control.Invoke“和"Dispatcher.Invoked”方法在幕后实际发生的事情。

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

https://stackoverflow.com/questions/11723708

复制
相关文章

相似问题

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