1

例外:必须在调用 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();
    }
}
4

1 回答 1

0

阿梅特兰,谢谢你的回复。

class Program
{
  static void Main(string[] args)
  {
      CefSharpWrapper.InitializeBrowser();
      MainAsync().Wait();
      CefSharpWrapper.ShutdownBrowser();
  }

  private static async Task MainAsync()
  {
      List<string> urls = new List<string>();
      urls.Add("https://google.com");

      CefSharpWrapper wrapper = new CefSharpWrapper();

      foreach (string url in urls)
      {
        await wrapper.GetResultAfterPageLoad(url);
      }
  }
}

public sealed class CefSharpWrapper
{
  private static ChromiumWebBrowser _browser;

  public static 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 static void ShutdownBrowser()
  {
    // Clean up Chromium objects.  You need to call this in your application otherwise
    // you will get a crash when closing.
      Cef.Shutdown();
  }
}
于 2021-05-27T15:15:47.750 回答