问题描述
Visual Studio 2017,Windows 10,.NET Framework 4.8,CefSharp WinForms 83.4.20,平台目标x64
创建了新的非常简单的CefSharp Windows窗体应用程序。我无法获取网页的html源。我想我已经查看过每一个CefSharp并在StackOverflow上进行异步同步问题-尝试了很多解决方案-我的头变得糊涂了。这是我关注的第一个问题-我有同样的问题。
Get HTML source code from CefSharp web browser
'browser.ViewSource();' 确实会弹出带有网页来源的记事本。但是,当我尝试获取带有源代码的字符串时,该任务似乎从未运行过。运行以获取网页源的任务显示--->状态= 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();
}
}
}
我的app.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
</startup>
</configuration>
我的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>
解决方法
看起来像一个僵局。那是一个正确的async/await
usage问题。
private async void WebBrowserFrameLoadEnded(ChromiumWebBrowser BrowserSender,FrameLoadEndEventArgs e)
{
if (e.Frame.IsMain)
{
string html1 = await GetBrowserSource(BrowserSender);
Debug.WriteLine(html1);
}
}
但是为什么不简单地这样做呢?
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);
}
}
请注意,Application.DoEvents()
isn't safe to use。