C#从其他线程访问元素

时间:2017-06-02 15:27:32

标签: c# multithreading

如何从其他线程访问元素?在这种情况下,我在主线程(GUI)中有一个richtextbox,我在辅助线程上运行一个方法。我想通过辅助线程访问richeditbox

private void Log(string input, Label lbl)
{
  lbl.Invoke(new Action(()=>
    {
      lbl.Text = "Status: " + input;
      Thread.Sleep(50);
    }));
}

void Run()
{
   foreach (string line in richTextBox1.Lines)
    {
      Log(line, label1);
      Thread.Sleep(500);
    }
}

private void button1_Click(object sender, EventArgs e)
{
  ThreadStart th = new ThreadStart(() => Run());
  Thread th2 = new Thread(th);
  th2.Start();
  //th2.Join();
}

显示以下错误:

  

无效的线程操作:control' richTextBox1'从a访问   不是创建它的线程。

2 个答案:

答案 0 :(得分:1)

你已经这样做了。您的Log方法显示正确的操作 - 使用Invoke在UI线程上运行一些代码。在这种情况下,您可以执行以下操作:

void Run()
{
    var getLines = new Func<object>(() => richTextBox1.Lines);
    var lines = (string[]) richTextBox1.Invoke(getLines);
    foreach (var line in lines)
    {
        Log(line, label1);
        Thread.Sleep(500);
    }
}

然而,这确实没有必要。看起来你真的想在单击按钮时读取Lines属性,然后将其传递给后台线程。

void Run(string[] lines)
{
    foreach (var line in lines)
    {
        Log(line, label1);
        Thread.Sleep(500);
    }
}

private void button1_Click(object sender, EventArgs e)
{
    var lines = richTextBox1.Lines;
    var th = new ThreadStart(() => Run(lines));
    var th2 = new Thread(th);
    th2.Start();
}

答案 1 :(得分:0)

这是另一个版本......不是你不应该在Log()方法中睡觉,因为它在UI线程中运行!

private void button1_Click(object sender, EventArgs e)
{
    ThreadStart th = new ThreadStart(() => Run());
    Thread th2 = new Thread(th);
    th2.Start();
}

void Run()
{
    string[] lines = (string[])richTextBox1.Invoke(new Func<string[]>(() => richTextBox1.Lines));
    foreach (string line in lines)
    {
        Log(line, label1);
        Thread.Sleep(500);
    }
}

private void Log(string input, Label lbl)
{
    lbl.Invoke(new Action(() =>
    {
        lbl.Text = "Status: " + input;
    }));
}