下面是我在运行Winforms GUI的线程中运行while(true)循环的函数。 我有一个按钮设置将文本数据放入inBuffer对象。这总是有效,但是当我从另一个线程放入缓冲区对象时,数据在Console.out.WriteLine语句中被检测,拉出和打印出来,但是它永远不会出现在Display(textBox)对象中
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';
}
}
编辑:这是一个单独的类,它通过静态缓冲区对象提供数据
答案 0 :(得分:0)
只有主窗口线程可以访问/更改控件...如果要从运行循环的线程更新UI,则需要使用Control.Invoke
方法将调用与主线程同步。 / p>
例如......
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);
}
答案 1 :(得分:0)
您可以使用MethodInvoker从其他线程然后GUI线程访问TextBox。制作一种方法,使用MethodInvoker访问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; }));
}
}
编辑您可以使用BeginInvoke
代替Invoke来异步调用它。详细了解此question中的Invoke
和BeginInvoke
。
void AssignToTextBox(TextBox txtBox, string value)
{
txtBox.BeginInvoke(new Action(()=>txtBox.Text = value ));
}