C# WinC窗体GUI将不接受来自其他线程的数据
下面是我在运行Winforms GUI的线程中的whiletrue循环中运行的函数。 我设置了一个按钮,将文本数据放入inBuffer对象。这总是有效的,但是当我从另一个线程放入缓冲区对象时,数据会在Console.out.WriteLine语句中被检测、提取和打印出来,但是它永远不会显示在Display textBox对象中C# WinC窗体GUI将不接受来自其他线程的数据,c#,multithreading,winforms,C#,Multithreading,Winforms,下面是我在运行Winforms GUI的线程中的whiletrue循环中运行的函数。 我设置了一个按钮,将文本数据放入inBuffer对象。这总是有效的,但是当我从另一个线程放入缓冲区对象时,数据会在Console.out.WriteLine语句中被检测、提取和打印出来,但是它永远不会显示在Display textBox对象中 public void put() { string strDisplayMe = ModemKind.MainClass.inBuffer
public void put()
{
string strDisplayMe = ModemKind.MainClass.inBuffer.MkRequest();
if (strDisplayMe != "")
{
Console.Out.WriteLine("FOUND SOMETHING IN BUFFER: " + strDisplayMe);
char[] DisplayMeArr = strDisplayMe.ToCharArray ();
for (int i = 0; i <= DisplayMeArr.Length -1; ++i)
{
this.display.Text += DisplayMeArr [i];
Thread.Sleep (100);
}
this.display.Text += '\n';
}
}
编辑:这是一个独立的类,与通过静态缓冲区对象提供数据的类不同,只有主窗口线程可以访问/更改控件。。。如果希望从运行循环的线程更新UI,则需要使用Control.Invoke方法将调用与主线程同步 例如
public void put()
{
string strDisplayMe = ModemKind.MainClass.inBuffer.MkRequest();
if (strDisplayMe != string.Empty)
{
char[] DisplayMeArr = strDisplayMe.ToCharArray();
for (int i = 0; i <= DisplayMeArr.Length -1; ++i)
{
this.UpdateUI(() => { this.display.Text += DisplayMeArr[i]; });
Thread.Sleep(100);
}
this.UpdateUI(() => { this.display.Text += '\n'; });
}
}
private void UpdateUI(Action handler)
{
this.Invoke(handler);
}
您可以使用MethodInvoker从其他线程然后从GUI线程访问TextBox。使用创建一个访问文本框的方法。您多次分配文本,考虑为性能分配一次,并使用StringBuilder进行字符串连接。
public void put()
{
string strDisplayMe = ModemKind.MainClass.inBuffer.MkRequest();
if (strDisplayMe != "")
{
Console.Out.WriteLine("FOUND SOMETHING IN BUFFER: " + strDisplayMe);
char[] DisplayMeArr = strDisplayMe.ToCharArray ();
for (int i = 0; i <= DisplayMeArr.Length -1; ++i)
{
AssignToTextBox(this.display, this.display.Text + DisplayMeArr [i]);
Thread.Sleep (100);
}
AssignToTextBox(this.display, this.display.Text + '\n');
}
}
void AssignToTextBox(TextBox txtBox, string value)
{
if(txtBox.InvokeRequired)
{
txtBox.Invoke(new MethodInvoker(delegate { txtBox.text = value; }));
}
}
查看Invoke,即this.display.InvokeMethodInvoker委托{this.display.Text+=DisplayMeArr[i];};你有机会看一下下面的问题吗?这似乎很好,但我不确定你所指的txtFolderName。实际上,线程。睡眠似乎是缓慢的调制解调器连接效果的一部分:D
void AssignToTextBox(TextBox txtBox, string value)
{
txtBox.BeginInvoke(new Action(()=>txtBox.Text = value ));
}