参数计数不匹配.-线程
本文关键字:线程 不匹配 参数 | 更新日期: 2023-09-27 18:20:20
我正试图使用WPF创建一个多客户端/服务器聊天小型应用程序,但我遇到了一些问题。不幸的是,当我按下"连接"按钮时,程序崩溃了。
到目前为止,我已经用客户端程序(用线程)做到了这一点:public delegate void UpdateText(object txt);
我得到了这个方法:
private void UpdateTextBox(object txt)
{
if (msg_log.Dispatcher.CheckAccess())
{
Dispatcher.Invoke(new UpdateText(UpdateTextBox),txt);
}
else
{
msg_log.Dispatcher.Invoke(new UpdateText(UpdateTextBox), txt);
}
}
我使用Button_Click事件连接到服务器,如下所示:
private void connect_Click(object sender, RoutedEventArgs e)
{
if ((nick_name.Text == "") || (ip_addr.Text == "") || (port.Text == ""))
{
MessageBox.Show("Nick name, IP Address and Port fields cannot be null.");
}
else
{
client = new Client();
client.ClientName = nick_name.Text;
client.ServerIp = ip_addr.Text;
client.ServerPort = port.Text;
Thread changer = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(UpdateTextBox));
changer.Start();
client.OnClientConnected += new OnClientConnectedDelegate(client_OnClientConnected);
client.OnClientConnecting += new OnClientConnectingDelegate(client_OnClientConnecting);
client.OnClientDisconnected += new OnClientDisconnectedDelegate(client_OnClientDisconnected);
client.OnClientError += new OnClientErrorDelegate(client_OnClientError);
client.OnClientFileSending += new OnClientFileSendingDelegate(client_OnClientFileSending);
client.OnDataReceived += new OnClientReceivedDelegate(client_OnDataReceived);
client.Connect();
}
}
请注意,OnClient*事件类似于private void client_OnDataReceived(object Sender, ClientReceivedArguments R) { UpdateTextBox(R.ReceivedData); }
因此,这些事件应该在msg_log TextBox 中写入一些类似"Connected"的文本
PS。txt对象曾经是一个字符串变量,但我更改了它,因为据我所知,ParameterizedThreadStart
只接受对象作为参数。
如有任何帮助,我们将不胜感激!
提前感谢,George
EDIT:按照Abe Heidebrecht的建议编辑UpdateTextBox方法。
您的Invoke
调用有一些问题。
- 您不需要创建对象数组来传递参数
- 传递
DispatcherPriority.Normal
是多余的(默认为Normal
) - 您没有将任何参数传递给第二个
Invoke
方法(这可能是发生错误的地方)
它应该是这样的:
private void UpdateTextBox(object txt)
{
if (msg_log.Dispatcher.CheckAccess())
{
Dispatcher.Invoke(new UpdateText(UpdateTextBox), txt);
}
else
{
msg_log.Dispatcher.Invoke(new UpdateText(UpdateTextBox), txt);
}
}
编辑StackOverflowException
这将导致StackOverflowException
,因为您正在无限循环中调用方法。之所以会发生这种情况,是因为您的方法只是一次又一次地调用自己。
Dispatcher.Invoke
所做的是在拥有Dispatcher
的线程上调用传递的委托。正因为msg_log
可能有一个不同的调度器,所以当您调用UpdateTextBox
时,您将一个委托传递给当前方法,这将导致无限循环。
您真正需要做的是在msg_log对象上调用一个方法,如下所示:
private void UpdateTextBox(object txt)
{
if (msg_log.Dispatcher.CheckAccess())
{
if (txt != null)
msg_log.Text = txt.ToString();
}
else
{
msg_log.Dispatcher.Invoke(new UpdateText(UpdateTextBox), txt);
}
}