我使用signalR将消息向上推送到服务器,然后向下推送到特定的客户端。
当我发送消息时,从我的signalR服务器向接收客户端发送一个ReceiveMessage函数调用,该函数映射到我的应用程序中的一个静态类函数。然后,静态类尝试执行new Chat()
(我的消息传递窗口类),以便在接收端打开一个消息窗口。
这会抛出calling thread must be STA, because many UI components require this.
我以前在简单的表单元素(如更改文本框)上使用过委托,但我不知道如何在这种情况下应用它。当我读到Invoke
时,它是在某种形式的表单对象上调用的,这在我的情况下是不存在的?
如何通过静态类函数调用创建和显示窗体的新实例
发布于 2012-07-30 22:44:40
使用当前GUI的线程调度程序。然后调用invoke。Par示例:
Application.Current.Dispatcher.Invoke(() => {
var win = new Window();
win.show();
});
发布于 2012-07-30 22:41:43
最简单的:使用App.MainWindow.Dispatcher
在GUI线程上执行创建:
App.MainWindow.Dispatcher.BeginInvoke((Action)(() => { new Chat(); }));
更难:创建一个新的STA线程,并在其上创建新窗口。
后一种选择比较困难,因为您将拥有多个GUI线程,并且需要确保跟踪操作,以便在每种情况下都使用正确的线程。除非您有特定的原因需要使用多个GUI线程,否则请坚持使用简单的选项。
发布于 2012-07-30 22:49:04
您必须在UI线程中调用代码。要做到这一点,您需要引用同步上下文。假设您从UI线程调用了以下代码:
SynchronizationContext syncContext = SynchronizationContext.Current;
因此,您获得了对上下文的引用。
然后,在回调方法中(在后台线程(而不是UI)中接收到消息后),您可以执行以下操作:
syncContext.Post((state) =>
{
Window w = new Window();
}, ...);
lambda表达式中的代码代表UI线程执行。据我所知,这是"Control.Invoke“和"Dispatcher.Invoked”方法在幕后实际发生的事情。
https://stackoverflow.com/questions/11723708
复制相似问题