我现在正在使用 namedpipe 和 C# 实现网络程序。在服务器程序的 main 方法中,我启动了一个名为“ReadingMessage”的线程,用于读取来自客户端程序的消息。在这个线程中,它需要根据客户端返回的消息来改变控件的属性(文本框的文本、标签的位置等)。因此,它在此过程中出现了跨线程错误(“ReadingMesssage between UI thread”)。我发现有两种方法可以解决这个问题
- 使用 Delegate 调用控件
- Form.CheckForIllegalCrossThreadCalls = false;
我测试了他们两个,但有一个问题。当窗体第一次启动时,控件的属性被更改而没有任何错误。当窗体关闭并第二次重新启动时,控件的属性不会更改,并且不会显示任何错误消息。我捕捉到指示控件属性更改的代码的断点。代码运行顺利,但问题仍然存在。
我不知道那是什么问题。因此,如果有人知道这个问题,请建议我...
更新:(在我的第一个问题中发布代码并更正一些错误)
该线程不在服务器程序的 main 方法中。我错了,因为我想简短地描述我的问题。现在,我将更详细地描述我的问题。在服务端程序的主窗体中有一个按钮点击事件。
//Main Form
public partial class MainForm : Form
{
private void btnButton_Click(object sender, EventArgs e)
{
AnotherForm aform = new AnotherForm(); //This is the form where threading run
aform.show();
}
}
//AnotherForm
public partial class AnotherForm : Form
{
private void CargoLoading_Load(object sender, EventArgs e)
{
(new System.Threading.Thread(readingMessage)).Start(myPipe);
}
}
private void readingMessage(Object myPipeObject) //Read the messages send from the client machine
{
while (true)
{
//Code of serverstream
SetTextofTextBox1("AnyText"); //Code where the properties of control are instructed to change
}
}
private void SetTextofTextBox1(string text)
{
if (this.txtTextBox1.InvokeRequired) //the debugger return false at second time of this form is opened
{
SetTextCallback d = new SetTextCallback(SetTextofTextBox1);
this.Invoke(d, new object[] { text });
}
else
{
this.txtTextBox1.Text = text;
this.txtTextBox1.Update();
}
}
这就是出现问题的所有代码。当“AnotherForm”第一次打开时,没关系。但是第二次再次打开时,控件的属性(TextBox1的文本)不受影响也不改变。在那里,我注意到调试器Control.InvokeRequired
在第二次返回 false 。真的很抱歉所有长时间的问题,因为我是程序员的新手。
仍然期待您的建议...
更新 2:
最后,我尝试了所有方法,但没有找到最好的解决方案。因此,我想建议大家避免这种情况,当你遇到像我这样的情况时,用另一个概念重写你的一些代码。