Task 中的 Invoke() 等待后继续

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

我正在尝试退出表单。但在退出之前,我需要确保一些无限任务已停止。这是我所拥有的一个最小的例子。

    public partial class Form1 : Form {
        private CancellationTokenSource _cts;
        private Task _backgroundTask;

        public Form1() {
            InitializeComponent();
            _cts = new CancellationTokenSource();

            _backgroundTask = Task.Run(() => DoWork(_cts.Token));
        }

        private async Task DoWork(CancellationToken token) {
            while (true) {
                try {
                    token.ThrowIfCancellationRequested();
                    await Task.Delay(1);

                    Debug.Write(">");
                    Invoke(() => { Text = DateTime.Now.ToString(); });
                    Debug.WriteLine("<");
                } catch (OperationCanceledException) {
                    // Expected
                    break;
                } catch (InvalidOperationException ex) {
                    // Not expected
                    ;
                }
            }
        }

        private async void button1_Click(object sender, EventArgs e) {
            _cts.Cancel();

            await _backgroundTask; 
            Debug.WriteLine("CLOSE");

            Close();
        }

有时代码会抛出

InvalidOperationException
并显示以下消息:
Invoke or BeginInvoke cannot be called on a control until the window handle has been created.

调试输出为:

><
><
><
Exception thrown: 'System.OperationCanceledException' in System.Private.CoreLib.dll
CLOSE
>Exception thrown: 'System.InvalidOperationException' in System.Windows.Forms.dll

推荐的解决方法似乎是只对异常进行空捕获,但我想知道为什么会发生这种情况?等待调用后循环如何继续运行?

c# winforms async-await
1个回答
0
投票

在任意线程中执行 WinForms 方法时,使用

Invoke
:

private async void button1_Click(object sender, EventArgs e) {
  _cts.Cancel();

  await _backgroundTask; 
  Debug.WriteLine("CLOSE");

  // Close - Win Forms method - should be called in the main thread context
  this.Invoke(Close);
}
© www.soinside.com 2019 - 2024. All rights reserved.