在窗体上调用Control与Invoke

问题描述 投票:2回答:1

例如,我使用以下代码:

private void startCalculcationButton_Click(object sender, EventArgs e) {
    int number;
    if (int.TryParse(this.numberTextBox.Text, out number)) {
    this.calculationResultLabel.Text = "(computing)";
        Task.Factory.StartNew(() => {
            int result = LongCalculation(number);
            this.calculationResultLabel.BeginInvoke(new ThreadStart(() => {
                this.calculationResultLabel.Text = result.ToString();
            }));
        });
    }
}

在那里,我调用this.calculationResultLabel.BeginInvoke(...)切换到UI-Thread,将Result设置为Label。

我也可以使用this.Invoke(...)(这是表格)。它在内部有所作为吗?

c# multithreading ui-thread
1个回答
1
投票

在窗体上调用Control与Invoke

我也可以使用this.Invoke(...)(这是表格)。它在内部有所作为吗?

听起来你在问两件不同的事情。你的标题是Invoke,但你的代码使用的是BeginInvoke,但你似乎也在询问是否要在表单或控件上调用。

  1. 你是否xxxInvoke形式或特定控制没有区别。两者都是UI元素,两者都可以为你编组调用。
  2. 如果你问的是InvokeBeginInvoke之间的区别,两种方法可以通过消息泵封送对UI线程的调用,它们之间存在差异。 Invoke可能导致线程僵局,而后者则不会。

无论如何,既然您正在使用Task并且在长时间运行的任务之后立即更新UI,那么您可以做得更好:

private void startCalculcationButton_Click(object sender, EventArgs e) {
    int number;
    if (int.TryParse(this.numberTextBox.Text, out number)) 
    {
        this.calculationResultLabel.Text = "(computing)"; // UI thread
        var result  = await Task.Run(() => 
                LongCalculation(number));  // threadpool thread

        calculationResultLabel.Text = result.ToString(); // UI thread
    }
}

不需要通过BeginInvoke或危险使用的Invoke进行繁琐的手动编组。

© www.soinside.com 2019 - 2024. All rights reserved.