Bub*_*bba 0 c# asynchronous async-await cefsharp
Visual Studio 2017、Windows 10、.NET Framework 4.8、CefSharp WinForms 83.4.20、平台目标 x64
创建了新的非常简单的 CefSharp Windows 窗体应用程序。我无法获取网页的 html 源代码。我想我已经查看了 StackOverflow 上的每个 CefSharp 和异步同步问题 - 尝试了很多解决方案 - 我的头已经变得糊涂了。这是我看到的第一个问题 - 我也有同样的问题。
'浏览器.ViewSource();' 确实会弹出一个记事本,其中包含网页的源代码。但是当我尝试使用源代码获取字符串时 - 任务似乎永远不会运行。运行以获取网页源的任务显示 ---> Status = WaitingForActivation ---> 并且永远不会返回源。
我尝试过异步到同步的转换 - 可能有十种不同的方式。没有工作。一个 StackOverflow 解决方案建议使用 Application.DoEvents() - 所以我什至尝试过。
希望有人有一些想法。这个浏览器似乎有很大的潜力 - 但我需要获取网页源 html。
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
using System.Diagnostics;
namespace Test1
{
public partial class Form1 : Form
{
public ChromiumWebBrowser browser;
public Form1()
{
InitializeComponent();
InitBrowser();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
browser.Dispose();
Cef.Shutdown();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
public void InitBrowser()
{
Cef.Initialize(new CefSettings());
browser = new ChromiumWebBrowser("https://google.com/");
this.Controls.Add(browser);
browser.Dock = DockStyle.Fill;
browser.FrameLoadEnd += OnWebBrowserFrameLoadEnded;
}
void OnWebBrowserFrameLoadEnded(object sender, FrameLoadEndEventArgs e)
{
ChromiumWebBrowser BrowserSender = (ChromiumWebBrowser)sender;
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(() => { WebBrowserFrameLoadEnded(BrowserSender, e); }));
}
else
{
WebBrowserFrameLoadEnded(BrowserSender, e);
}
}
void WebBrowserFrameLoadEnded(ChromiumWebBrowser BrowserSender, FrameLoadEndEventArgs e)
{
string html1 = null;
Task<String> taskString1;
if (e.Frame.IsMain)
{
//browser.ViewSource();
taskString1 = Task.Run(() => GetBrowserSource(browser));
while (taskString1.Status != TaskStatus.RanToCompletion)
{
Application.DoEvents();
System.Threading.Thread.Sleep(100);
}
html1 = taskString1.Result;
Debug.WriteLine("");
}
}
async Task<string> GetBrowserSource(ChromiumWebBrowser Browser)
{
return await Browser.GetMainFrame().GetSourceAsync();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的应用程序配置
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
</startup>
</configuration>
Run Code Online (Sandbox Code Playgroud)
我的packages.config
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="cef.redist.x64" version="83.4.2" targetFramework="net452" />
<package id="cef.redist.x86" version="83.4.2" targetFramework="net452" />
<package id="CefSharp.Common" version="83.4.20" targetFramework="net452" />
<package id="CefSharp.WinForms" version="83.4.20" targetFramework="net452" />
</packages>
Run Code Online (Sandbox Code Playgroud)
看上去陷入了僵局。这就是正确async/await 使用的问题。
private async void WebBrowserFrameLoadEnded(ChromiumWebBrowser BrowserSender, FrameLoadEndEventArgs e)
{
if (e.Frame.IsMain)
{
string html1 = await GetBrowserSource(BrowserSender);
Debug.WriteLine(html1);
}
}
Run Code Online (Sandbox Code Playgroud)
但为什么不简单地这样做呢?
private async void OnWebBrowserFrameLoadEnded(object sender, FrameLoadEndEventArgs e)
{
if (e.Frame.IsMain)
{
ChromiumWebBrowser browserSender = (ChromiumWebBrowser)sender;
string html = await browserSender.GetMainFrame().GetSourceAsync();
Debug.WriteLine(html);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,Application.DoEvents() 使用起来并不安全。