winforms 在C#中使用异步委托调用Invoke()

8cdiaqws  于 2023-04-21  发布在  C#
关注(0)|答案(1)|浏览(132)

我有一个WinForms(.NET 4.7.2)应用程序从串行条形码扫描仪阅读数据并将其返回到GUI。
我的async SerialDataReceivedEventHandler是:

private async void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
   if (_serialPort != null && _serialPort.IsOpen)
   {
       string data = _serialPort.ReadExisting();
       if (this.InvokeRequired)
       {
          this.Invoke(new Func<Task>(async () => await HandleDataFromScannerAsync(data)));
       }             
   }
}

private async Task HandleDataFromScannerAsync(string text) {
...do async stuff...
}

我必须在Port_DataReceived()中使用Invoke(),因为串行扫描仪的数据在不同的线程中读取。
这段代码可以工作,但是...它是否正确地异步?我知道调用async void方法。
我读了Stephen Cleary关于Synchronous and Asynchronous Delegate Types的文章,这就是我使用new Func<Task>(async () => await HandleDataFromScannerAsync(data))的原因。
所以当调用Invoke()时,不应该以某种方式等待它吗?像await this.Invoke(...)或以某种方式。我尝试了BeginInvoke()而不是Invoke()。我理解其中的区别,但我不确定哪种方式是正确的。两种方式似乎都可以工作。
所以我的问题是-如何正确地调用Invoke()与异步委托?

nhn9ugyo

nhn9ugyo1#

这对我很有效:

public async Task<string> ExecuteScript(string script)
    {
        Func<Task<string>> func = async () =>
        {
            await webView.CoreWebView2.ExecuteScriptAsync(script)
        };
        if (InvokeRequired)
        {
            var task = (Task<string>)Invoke(func);
            return await task;
        }
        else
        {
            return await func();
        }
    }

相关问题