[英]Asynchronous console program hangs on completion of task using CefSharp
In my quest to create the perfect string result = browser.Browse(url)
method, I have created a simple class library to demonstrate CefSharp.为了创建完美的string result = browser.Browse(url)
方法,我创建了一个简单的类库来演示 CefSharp。 The code for that is:代码是:
public class CefSharpHeadlessBrowser
{
public CefSharpHeadlessBrowser()
{
Cef.Initialize(new CefSettings { CachePath = "cache" }, false, true);
}
public string Browse(string url)
{
Task<string> result;
var browserSettings = new BrowserSettings { WindowlessFrameRate = 1 };
using (var browser = new ChromiumWebBrowser(url, browserSettings))
{
browser.WaitForBrowserToInitialize();
browser.LoadPageAsync();
// Wait awhile for Javascript to finish executing.
Thread.Sleep(2000);
result = browser.GetSourceAsync();
Thread.Sleep(100);
}
return result.Result;
}
}
public static class CefExtensions
{
public static void WaitForBrowserToInitialize(this ChromiumWebBrowser browser)
{
while (!browser.IsBrowserInitialized)
{
Task.Delay(100);
}
}
public static Task LoadPageAsync(this IWebBrowser browser)
{
var tcs = new TaskCompletionSource<bool>();
EventHandler<LoadingStateChangedEventArgs> handler = null;
handler = (sender, args) =>
{
if (!args.IsLoading)
{
browser.LoadingStateChanged -= handler;
tcs.TrySetResult(true);
}
};
browser.LoadingStateChanged += handler;
return tcs.Task;
}
}
This is the test harness, in a separate console project that references the CefSharpHeadlessBrowser project:这是引用 CefSharpHeadlessBrowser 项目的单独控制台项目中的测试工具:
class Program
{
static void Main(string[] args)
{
const string searchUrl = "https://www.google.com";
var browser = new CefSharpHeadlessBrowser();
var result = browser.Browse(searchUrl);
Console.Write(result);
}
}
This actually works;这确实有效; it gets the HTML page source properly and displays it in the console window, just as it should.它正确获取 HTML 页面源代码并将其显示在控制台窗口中,就像它应该的那样。 But here's the problem: the console program hangs after displaying the page source.但问题来了:控制台程序在显示页面源后挂起。 It should exit immediately.它应该立即退出。 Which must mean that I'm doing something wrong with the asynchronous operations and causing a deadlock.这一定意味着我在异步操作上做错了并导致了死锁。
What could be the issue?可能是什么问题?
CefSharp has a Shutdown command; CefSharp 有一个 Shutdown 命令; I was able to solve the problem by adding the following method to the CefSharpHeadlessBrowser
class:我能够通过将以下方法添加到CefSharpHeadlessBrowser
类来解决问题:
public void Shutdown()
{
Cef.Shutdown();
}
And then changing the Test Harness to:然后将测试线束更改为:
class Program
{
static void Main(string[] args)
{
const string searchUrl = "https://www.google.com";
var browser = new CefSharpHeadlessBrowser();
var result = browser.Browse(searchUrl);
Console.WriteLine(result);
browser.Shutdown(); // Added
}
}
This undoubtedly frees up any remaining threads that are running.这无疑会释放任何剩余的正在运行的线程。
I'll probably make the class IDisposable
and wrap the calling code in a using
statement.我可能会创建IDisposable
类并将调用代码包装在using
语句中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.