C#中的文本框的异步写入被覆盖 [英] Asynchronous Writes To Textbox in C# are Overwritten

查看:211
本文介绍了C#中的文本框的异步写入被覆盖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,其中两个线程异步写入单个文本框。它有效,除了写入文本框的第二个线程将覆盖第一个线程刚刚写入的行。对这个问题的任何想法或见解将不胜感激。我正在使用Microsoft Visual C#2008 Express Edition。谢谢。

  delegate void SetTextCallback(string text); 

private void SetText(string text)
{
this.textBox1.Text + = text;
this.textBox1.Select(textBox1.Text.Length,0);
this.textBox1.ScrollToCaret();
}

private void backgroundWorkerRx_DoWork(object sender,DoWorkEventArgs e)
{
string sText =;

//有些接收工作和构建sText

如果(textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d,new object [] {sText});
}
else
{
SetText(sText);
}
}


解决方案

strong> EDIT :这可能无法解决问题,但您可能想要处理BackgroundWorkers的 ProgressChanged 事件并将文本设置在那里。



例如:

  void backgroundWorker_ProgressChanged(object sender,ProgressChangedEventArgs e){
SetText((string)e.UserState);
} //使此方法处理两个worker的RunWorkerCompleted

//在DoWork中:
worker.ReportProgress(0,sText);

ProgressChanged在UI线程上触发,因此您不需要调用调用



顺便说一下,您应该将 SetText 重命名为 AppendText 使代码更清晰。

此外,您还可以使用内置代理 Action< String> 而不是自己的 SetTextCallback 委托类型。



编辑:另外,您应该将 InvokeRequired 支票移至 SetText



例如:

  private void AppendText(string text){
if(textBox1.InvokeRequired){
textBox1.Invoke(new Action< string>(AppendText),text);
return;
}
this.textBox1.AppendText(text);
this.textBox1.SelectionStart = textBox1.TextLength;
this.textBox1.ScrollToCaret();
}


I have an application wherein two threads write asynchronously to a single textbox. It works, except that the second thread to write to the textbox overwrites the line that the first thread just wrote. Any thoughts or insight into the problem would be greatly appreciated. I am using Microsoft Visual C# 2008 Express Edition. Thanks.

  delegate void SetTextCallback(string text);

  private void SetText(string text)
  {
     this.textBox1.Text += text;
     this.textBox1.Select(textBox1.Text.Length, 0);
     this.textBox1.ScrollToCaret();
  }

  private void backgroundWorkerRx_DoWork(object sender, DoWorkEventArgs e)
  {
     string sText = "";

     // Does some receive work and builds sText

     if (textBox1.InvokeRequired)
     {
        SetTextCallback d = new SetTextCallback(SetText);
        this.Invoke(d, new object[] { sText });
     }
     else
     {
        SetText(sText);
     }
  }

解决方案

EDIT: This might not solve the problem, but you might want to handle the ProgressChanged event of the BackgroundWorkers and set the text there.

For example:

void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
    SetText((string)e.UserState);
}  //Make this method handle the RunWorkerCompleted for both workers

//In DoWork:
    worker.ReportProgress(0, sText);

ProgressChanged is fired on the UI thread, so you don't need to call Invoke.

By the way, you should probably rename SetText to AppendText to make the code clearer.
Also, you can use the built-in delegate Action<String> instead of making your own SetTextCallback delegate type.

EDIT: Also, you should probably move the InvokeRequired check to SetText.

For example:

private void AppendText(string text) {
    if(textBox1.InvokeRequired) {
        textBox1.Invoke(new Action<string>(AppendText), text);
        return;
    }
    this.textBox1.AppendText(text);
    this.textBox1.SelectionStart = textBox1.TextLength;
    this.textBox1.ScrollToCaret();
}

这篇关于C#中的文本框的异步写入被覆盖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆