我使用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