2015-07-20 70 views
1

我在這裏看到了其他類似的問題,但我似乎無法找到針對我的特定問題的解決方案。從另一個班級和線程更新UI項目

我正在編寫一個Twitch Bot,當從服務器收到消息時,需要更新主窗體上的列表框。我改變了我的TwitchBot.cs類的自定義事件稱爲OnReceive,看起來像這樣:

public delegate void Receive(string message); 
public event Receive OnReceive; 

private void TwitchBot_OnReceive(string message) 
{ 
    string[] messageParts = message.Split(' '); 
    if (messageParts[0] == "PING") 
    { 
     // writer is a StreamWriter object 
     writer.WriteLine("PONG {0}", messageParts[1]); 
    } 
} 

的事件在我的TwitchBot類的Listen()方法提出:

private void Listen() 
{ 
    //IRCConnection is a TcpClient object 
    while (IRCConnection.Connected) 
    { 
     // reader is a StreamReader object. 
     string message = reader.ReadLine(); 

     if (OnReceive != null) 
     { 
      OnReceive(message); 
     } 
    } 
} 

連接到IRC當後端,我稱之爲從一個新的線程Listen()方法:

Thread thread = new Thread(new ThreadStart(Listen)); 
thread.Start(); 

然後我訂閱了OnReceive事件中的主要形式使用下面的行:

// bot is an instance of my TwitchBot class 
bot.OnReceive += new TwitchBot.Receive(UpdateChat); 

最後,UpdateChat()是用於在其上更新列表框的主要形式的方法:

private void UpdateChat(string message) 
{ 
    lstChat.Items.Insert(lstChat.Items.Count, message); 
    lstChat.SelectedIndex = lstChat.Items.Count - 1; 
    lstChat.Refresh(); 
} 

當我連接到服務器,並且Listen()方法運行,我得到一個InvalidOperationException,其中說:「其他信息:跨線程操作無效:控制'lstChat'從一個線程訪問,而不是它創建的線程。」

我查過了如何從另一個線程更新UI,但只能找到WPF的東西,我正在使用winforms。

+1

可能重複[跨線程操作無效:控制從比它創建的線程以外的線程訪問(http://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-from-a-thread-other-the- –

+0

我已經看過那個鏈接,但仍然沒有解決這個問題。你能解釋一下我在那個鏈接中尋找什麼/它與我的問題有什麼關係?我不明白如何特別使用[System.Windows.Forms.Control.Invoke](https://msdn.microsoft.com/en-us/library/System.Windows.Forms.Control.Invoke.aspx)它在該鏈接中引用了我在問題中發佈的代碼。 –

回答

1

您應該檢查的Invoke for UI thread

private void UpdateChat(string message) 
{ 
    if(this.InvokeRequired) 
    { 
     this.Invoke(new MethodInvoker(delegate { 
      lstChat.Items.Insert(lstChat.Items.Count, message); 
      lstChat.SelectedIndex = lstChat.Items.Count - 1; 
      lstCat.Refresh(); 
     }));   
    } else { 
      lstChat.Items.Insert(lstChat.Items.Count, message); 
      lstChat.SelectedIndex = lstChat.Items.Count - 1; 
      lstCat.Refresh(); 
    } 
} 
+0

太棒了!這正是我需要的。感謝您鏈接這些內容豐富的文章,並向我展示如何使用invoke。這現在很好用! –