例外:必须在调用 Cef.Initialize 的同一线程上调用 Cef.Shutdown - 通常是您的 UI 线程。如果您在 UI 线程以外的线程上调用 Cef.Initialize,那么您将需要在同一个线程上调用 Cef.Shutdown。Cef.Initialize 在 ManagedThreadId: 1 上被调用,而 Cef.Shutdown 在 ManagedThreadId: 4 上被调用
class Program
{
static void Main(string[] args)
{
MainAsync().Wait();
}
private static async Task MainAsync()
{
List<string> urls = new List<string>();
urls.Add("https://google.com");
CefSharpWrapper wrapper = new CefSharpWrapper();
wrapper.InitializeBrowser();
foreach (string url in urls)
{
await wrapper.GetResultAfterPageLoad(url);
}
wrapper.ShutdownBrowser();
}
}
public sealed class CefSharpWrapper
{
private ChromiumWebBrowser _browser;
public void InitializeBrowser()
{
Cef.Initialize(new CefSettings());
_browser = new ChromiumWebBrowser();
AutoResetEvent waitHandleOnBrowserInitialized = new AutoResetEvent(false);
EventHandler onBrowserInitialized = null;
onBrowserInitialized = async (sender, e) =>
{
_browser.BrowserInitialized -= onBrowserInitialized;
waitHandleOnBrowserInitialized.Set();
};
_browser.BrowserInitialized += onBrowserInitialized;
waitHandleOnBrowserInitialized.WaitOne();
}
public Task<bool> GetResultAfterPageLoad(string pageUrl)
{
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
EventHandler<LoadingStateChangedEventArgs> onPageLoaded = null;
// An event that is fired when the first page is finished loading.
// This returns to us from another thread.
onPageLoaded = async (sender, args) =>
{
// Check to see if loading is complete - this event is called twice, one when loading starts
// second time when it's finished
// (rather than an iframe within the main frame).
if (!args.IsLoading)
{
// Remove the load event handler, because we only want one snapshot of the initial page.
_browser.LoadingStateChanged -= onPageLoaded;
tcs.SetResult(true);
}
};
_browser.LoadingStateChanged += onPageLoaded;
_browser.Load(pageUrl);
return tcs.Task;
}
public void ShutdownBrowser()
{
// Clean up Chromium objects. You need to call this in your application otherwise
// you will get a crash when closing.
Cef.Shutdown();
}
}