我真的很想理解并解决这个困扰我几天的问题。我读了数百个线程,但无法让它工作。
我有一个主要表单,在辅助表单上有一个 WebView2 控件。目的是从主窗体控制WebView2。它们的配置如下:
我的目标是使用主表单将一些 HTML 代码从辅助表单加载到 WebView2 中,然后对该页面进行屏幕截图。 HTML 加载部分正在工作,因此我接下来将重点关注屏幕截图问题。我使用这个方法来截图。当直接调用时它本身工作正常,但是当我从线程或后台工作者调用它时它会失败。是的,我知道,由于“跨线程调用”,这种行为是预期的。请多多包涵!
理想情况下,我认为它应该像这样工作(过于简化的代码):
private void PrimaryForm_Load(...)
{
_secondaryForm = new SecondaryForm();
_secondaryForm.Show();
}
private void Button_Click(...)
{
Thread thread = new Thread(HeavyWork);
thread.Start();
}
private void HeavyWork()
{
// this method will run a few hundred times
Task<string> task = CaptureScreenshotAsync();
string str = task.Result;
// further process the str...
}
private async Task<string> CaptureScreenshotAsync()
{
// it will throw a cross-thread exception
return await _secondaryForm.webView.CoreWebView2.CallDevToolsProtocolMethodAsync("Page.captureScreenshot", "{}");
}
正如你所看到的
这里我尝试过以几种方式调用它,但没有成功。另外,使其同步。尝试过this
、this和that等。我无法让它正常工作。
我也尝试过像这样直接调用 HeavyWork
方法:
private void Button_Click(...)
{
HeavyWork();
}
或这个
。
我自己无意中发现的唯一“黑客”是在得到任务结果之前“睡觉”一点,如下所示:
private void HeavyWork()
{
Task<string> task = CaptureScreenshotAsync();
Sleep(250);
string str = task.Result;
}
这就是
Sleep
方法:
private void Sleep(int interval)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < interval)
{
Application.DoEvents();
}
stopwatch.Stop();
}
我将非常感谢任何帮助。谢谢!
如果您使用异步方法,则应该使每个必须处理该函数结果的函数也异步。然后,您可以简单地调用顶部异步的最后一个函数,而无需等待它。异步函数内的 Invoke 调用应该可以工作。我看不出它不起作用的原因。当您从想要其结果的函数调用异步函数时,也不要忘记等待运算符。