从另一个类和线程更新UI项 [英] Update UI item from another class and thread
问题描述
我在这里还看到了其他类似的问题,但似乎找不到针对我特定问题的解决方案.
I've seen other similar questions here but I can't seem to find a solution for my specific problem.
我正在写一个Twitch Bot,当从服务器收到消息时,需要更新主窗体上的列表框.我在TwitchBot.cs类中创建了一个名为OnReceive
的自定义事件,如下所示:
I'm writing a Twitch Bot and need to update a listbox on the main form when a message is received from the server. I made a custom event in my TwitchBot.cs class called OnReceive
that looks like this:
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()
方法中引发:
The event is raised in the Listen()
method of my TwitchBot
class:
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()
方法:
When connecting to the IRC back-end, I call the Listen()
method from a new thread:
Thread thread = new Thread(new ThreadStart(Listen));
thread.Start();
然后,我使用以下行以主要形式订阅OnReceive
事件:
I then subscribed to the OnReceive
event in the main form using the following line:
// bot is an instance of my TwitchBot class
bot.OnReceive += new TwitchBot.Receive(UpdateChat);
最后,UpdateChat()
是主要形式的方法,用于更新其上的列表框:
Finally, UpdateChat()
is a method in the main form used to update a listbox on it:
private void UpdateChat(string message)
{
lstChat.Items.Insert(lstChat.Items.Count, message);
lstChat.SelectedIndex = lstChat.Items.Count - 1;
lstChat.Refresh();
}
当我连接到服务器并且Listen()
方法运行时,我得到一个InvalidOperationException
,上面写着其他信息:跨线程操作无效:控制'lstChat'是从不是该线程的线程访问的创建于".
When I connect to the server and the Listen()
method runs, I get an InvalidOperationException
that says "Additional information: Cross-thread operation not valid: Control 'lstChat' accessed from a thread other than the thread it was created on."
我已经研究了如何从不同的线程更新UI,但是只能找到WPF的东西,而我正在使用winforms.
I've looked up how to update UI from a different thread but can only find things for WPF and I'm using winforms.
推荐答案
您应检查 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();
}
}
这篇关于从另一个类和线程更新UI项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!