2011-08-28 33 views
7

我有一個服務器類,它基本上等待來自客戶端的連接。在該類中,我創建了一個NetworkStream對象,以便能夠從客戶端接收字節。因爲NetworkStream.Read()方法不是異步的(意味着它將等待,直到它從客戶端讀取字節以繼續執行類似於messagebox方法的代碼),那麼我必須讀取單獨線程中的字節,以便如果程序碰巧等待讀取數據,則使用程序的用戶仍然可以與程序交互。來自不同線程的訪問對象

反正很多對象都屬於該線程。一個例子是我有一個名爲日誌的List。我使用該列表來了解服務器的狀態。也許它正在監聽連接,或者它的狀態是「連接」或「斷開」。

所以,如果我這樣做:

Server myServer = new Server("192.168.0.120","1300"...\\ I pass the appropite parameters in order to instantiate it 

//... 
.. then I am able to latter look at the log as 
string foo = myServer.Log[0] for example. 

,因爲我想知道當日志被更新,服務器類我已經創建了一個事件爲:

public delegate void onUpdateHandler(string newStatus); 
    public event onUpdateHandler onUpdate = delegate { }; 

然後我火事件在服務器類爲:

onUpdate("waitingForConnection"); 

和我收到這些事件與方法:

enter image description here

但如果我嘗試做一些NEWSTATUS我得到的錯誤,指出:

System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it. 

所以我怎麼能傳遞一個對象與事件?


編輯

,所以我也注意到,如果我這樣做:

enter image description here

我也得到一個錯誤!

但是當我做呼叫從一個按鈕,同樣的事情:

// SERVER IS RUNNING BEFORE CALLING THIS METHOD 
    private void button3_Click(object sender, RoutedEventArgs e) 
    { 

     listView1.Items.Add("my own string"); 

    } 

我沒有得到一個錯誤!

爲什麼我在事件中遇到錯誤,並且在用常規按鈕調用時沒有遇到錯誤。

回答

12

的問題是,該線程試圖訪問ListView控件這是一個DependencyObject具有線程關聯,使用Dispatcher到UI線程上執行這樣的方法,如:

Application.Current.Dispatcher.Invoke((Action)(() => 
{ 
    listView1.Items.Add(newStatus); 
})); 

另請參見threading model reference獲取更多信息。

+0

我的方法我得到一個錯誤,指出:不能轉換lambda表達式鍵入'System.Delegate',因爲它不是一個委託類型 –

+0

@TonoNam:哦,是的,你需要投它,或明確創建一個行動。 –

+0

@Tono,lambda必須被鑄造成某種代表類型,請參閱我的編輯。 – svick

1

問題不在於您嘗試使用您發送給該方法的值進行操作,而是您嘗試使用該方法的問題。

事件處理程序仍在後臺線程中運行,並且從那裏您不能使用任何UI控件,因爲它們屬於主線程。

處理的常用方法是使用CheckAccess方法來檢查,如果你需要切換踏板,以及Invoke方法來交班工作,主線程:當我把裏面

void server_onUpdate(string newStatus) { 
    if (!listView1.Dispatcher.CheckAccess()) { 
    listView1.Dispatcher.Invoke(server_onUpdate, newStatus) 
    } else { 
    listView1.Items.Add(newStatus); 
    } 
} 
+0

根據標籤,這不是WinForms ... –

+0

@ H.B .:我已經糾正了這一點。 – Guffa

+0

@Guffa很好的解釋謝謝 –