我使用TcpListener类来处理充当套接字服务器的WPF GUI应用程序。 TcpListener配置为在收到监听套接字的数据时进行回调。但问题是TcpListener回调来自另一个线程,并导致以下错误,当我尝试从回调中触摸GUI时:在不同线程之间进行C#回调
“跨线程操作无效:从非线程访问的控制'滑块'它创建于“。
任何想法如何解决这个问题?
我很熟悉Qt,它可以将信号/插槽系统发送到另一个线程。 C#中是否有类似的功能?
我使用TcpListener类来处理充当套接字服务器的WPF GUI应用程序。 TcpListener配置为在收到监听套接字的数据时进行回调。但问题是TcpListener回调来自另一个线程,并导致以下错误,当我尝试从回调中触摸GUI时:在不同线程之间进行C#回调
“跨线程操作无效:从非线程访问的控制'滑块'它创建于“。
任何想法如何解决这个问题?
我很熟悉Qt,它可以将信号/插槽系统发送到另一个线程。 C#中是否有类似的功能?
你应该在UI线程中调用你的代码。尝试使用调度
Application.Current.Dispatcher.Invoke(Callback):
您需要使用WPF Dispatcher类调用该方法返回到UI线程 - 看
您要使用的方法Dispatcher.Invoke。
如果您this
是DependencyObject
类,你可以简单地使用:
this.Dispatcher.Invoke((Action)(() =>
{
slider.DoAnythingYouWant();
}));
您不能直接从独立访问GUI元素(例如,从线程池中取出用于异步操作或与主题类直接创建)。你需要做的是通过调度员执行的动作,例如:在调度员如何管理线程
Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => slider.Text = "mystuff"));
有关详细信息,请参阅下面的MSDN链接:
http://msdn.microsoft.com/en-us/library/vstudio/system.windows.threading.dispatcher
访问某些GUI元素不仅是我不是这个意思。我真正想要的是从另一个触发我自己的UI线程方法,这样它的行为就像通过某个按钮按下来调用方法一样。我可以使用Dispactcher来做到这一点吗?即那么我可以访问所有的UI类的东西,而不必担心错误的线程。 – TeroK
找到完全在UI线程中完成回调函数的解决方案(CommandHandler是MainForm中的方法,并从AsynchronousSocketListener的另一个线程中调用):
void CommandHandler()
{
if (InvokeRequired)
{
/* If called from a different thread, we must use the Invoke method to marshal the call to the proper thread. */
BeginInvoke(new AsynchronousSocketListener.ReadHandler(CommandHandler));
return;
}
else
{
//do UI thread code here
}
}
对于那些可能需要工作示例的东西,在Basler Pylon 4.0库示例程序PylonLiveView中以这种方式完成。
您需要将回调中的代码编组为UI线程中执行的任何可能触发UI控件更改的事件(在您的情况下为滑块)。取决于你的代码是什么样的,你可以通过使用'Control.Invoke'或'Dispatcher'类 –
来完成。是的,在WPF中它是'Dispatcher'。基本上它会调用一个调用到UI消息队列以在UI线程上处理。 –
topc似乎被覆盖[这里] [1]。 [1]:http://stackoverflow.com/questions/4016921/wpf-invoke-a-control – Codor