线程通信

threads communication

提问人:Sridhar 提问时间:12/23/2012 更新时间:12/24/2012 访问量:127

问:

我有一个带有文本框和按钮的表单。单击按钮后,我正在创建一个线程并调用它进行某些操作。线程完成调用的任务后,我想用结果更新文本框。

任何人请帮助我如何在没有线程冲突的情况下实现这一目标。

C# 多线程

评论


答:

3赞 Reed Copsey 12/23/2012 #1

使用 .NET 4.0 的类,这要简单得多:Task

private void button_Click(object sender, EventArgs e)
{
    Task.Factory.StartNew( () => 
    {
         return DoSomeOperation();
    }).ContinueWith(t =>
    {
         var result = t.Result;
         this.textBox.Text = result.ToString(); // Set your text box
    }, TaskScheduler.FromCurrentSynchronizationContext());
}

如果使用的是 .NET 4.5,可以使用新的异步支持进一步简化此操作:If you're using .NET 4.5, you can simplify this further using the new async support:

private async void button_Click(object sender, EventArgs e)
{
    var result = await Task.Run( () => 
    {
         // This runs on a ThreadPool thread 
         return DoSomeOperation();
    });

    this.textBox.Text = result.ToString();
}

评论

2赞 Marc Gravell 12/23/2012
好吧,我会称“更简单”为可疑。如果您只是使用 ,IIRC 默认使用 sync-context,它可能会更简单await
0赞 Reed Copsey 12/24/2012
@MarcGravell我发现这比带有调用调用的线程简单得多,但这是个人喜好。等待的好点 - 我也会将其添加为一个选项。
0赞 Vilx- 12/23/2012 #2

您需要使用 Control.Invoke 在其自己的线程中操作窗体。

0赞 Marc Gravell 12/23/2012 #3

简单地说,在线程操作结束时:

/// ... your code here
string newText = ...

textBox.Invoke((MethodInvoker) delegate {
    textBox.Text = newText;
});

该用法使用 message-queue 将工作传递给 UI 线程,因此是 UI 线程执行该行。Control.InvoketextBox.Text = newText;

0赞 detrumi 12/23/2012 #4

使用 ,将任务分配给事件,并使用事件更新文本框。然后,您可以使用 开始任务。BackgroundWorkerDoWorkRunWorkerCompletedRunWorkerAsync()

0赞 geniaz1 12/23/2012 #5

您可以使用此处显示的解决方案:

如何从 C# 中的另一个线程更新 GUI?

下次在询问之前先搜索一下。