2009-03-06 50 views
3

我有一個tcp服務器,當一個客戶端連接時,它會創建一個新線程並將它添加到它,但是每次我嘗試訪問有關連接的信息或任何有關它的信息時,即使保持有多少客戶端連接,我得到了一個跨線程非法異常或類似的東西。C#:我如何優雅地或簡單地進行交叉線程調用?

我讀過幾個關於代理,調用和反射的教程,但所有的例子或教程都讓我困惑,因爲做某個調用的方式失敗了。

有沒有這樣做的優雅或簡單的方法?我是否需要學習如何首先做其他事情?還是我只是讓事情比他們更復雜?任何建議,鏈接或提示最受讚賞和接受。

回答

0

我想你會得到這個交叉線程異常,因爲你試圖從你的線程代碼更新屏幕元素。如果你需要這樣做,你可以使用匿名方法得到一個簡單的解決方案。

假設您想要將一個項目添加到名爲ListBoxLog的列表框中。此代碼會從任何線程做的伎倆:

ListBoxLog.Invoke((MethodInvoker)delegate { ListBoxLog.Items.Add("Done"); }); 

還有檢查.InvokeRequired你可以檢查,看看是否調用是nessecary屬性。你通常會在一個可以被主UI線程和任何後臺線程調用的函數中檢查該屬性。

您也可以像使用Invoke一樣使用BeginInvoke。 BeginInvoke完全是異步的,不會等待代理中的代碼完成。

0

使用代表事件

這將是我最好的答案。

http://www.codeproject.com/KB/cs/Cross_thread_Events.aspx

+0

其次CodeProject文章,儘管我更喜歡BackgroundWorker解決方案(也在文章中)。但是,在許多情況下,異步調用事件是很好的。 – OregonGhost 2009-03-06 07:47:50

+0

我必須承認我對BackgroundWorker類沒有太多的工作,但我會着眼於此。謝謝。 – 2009-03-06 07:51:30

1

我想你直接從你的客戶端連接線程進入UI。不是很好。相反,考慮使用MVP模式的一些變體來將表示邏輯從視圖中分離出來。因此,您的「連接線程」將與一些中介交談,主持人將與同一個中介交談,並交出一些數據以供查看顯示。

就跨線程操作而言,特別是UI線程操作,我發現SynchronizationContext在你想編組從非UI線程到UI線程的調用時是非常有用的。有關更深入的討論,請參見this article