我有一个 WinForms (.NET 4.7.2) 应用程序从串行条码扫描仪读取数据并将其返回到 GUI。
我的异步 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...
}
我必须在
Invoke()
中使用Port_DataReceived()
,因为串行扫描仪的数据是在不同的线程中读取的。
此代码可以正常工作,但是......它是否正确异步?我知道调用
async void
方法。
我阅读了 Stephen Cleary 关于同步和异步委托类型的文章,这就是我使用
new Func<Task>(async () => await HandleDataFromScannerAsync(data))
的原因。
所以调用
Invoke()
时,不应该以某种方式等待吗?像await this.Invoke(...)
或以某种方式。我试过BeginInvoke()
而不是Invoke()
。我理解其中的区别,但我不确定哪种方法是正确的。两种方法似乎都有效。
所以我的问题是 - 如何使用异步委托正确调用
Invoke()
?
这对我有用:
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();
}
}