【问题标题】:CefSharp winfoms Page load and waitCefSharp winfoms 页面加载并等待
【发布时间】:2019-10-04 18:26:11
【问题描述】:

我正在我的应用程序中处理Cefsharp Offscreen。文档中提供的加载页面代码是:

 const string testUrl = "https://github.com/cefsharp/CefSharp/wiki/Quick-Start";
  var settings = new CefSettings()
        {
   //By default CefSharp will use an in-memory cache, you need to specify a Cache Folder to persist data
   CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache")
        };

   //Perform dependency check to make sure all relevant resources are in our output directory.
   Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);

   // Create the offscreen Chromium browser.
   browser = new ChromiumWebBrowser(testUrl);

   // An event that is fired when the first page is finished loading.
   // This returns to us from another thread.
   browser.LoadingStateChanged += BrowserLoadingStateChanged;
   Cef.Shutdown();

但我想要这样的东西

browser = new ChromiumWebBrowser(); //without testUrl
 // and then 
browser.Load(testUrl).Wait();// and wait something like that;
// load url and wait unit page is fully loaded then go to next line

我找不到任何解决方案。

【问题讨论】:

  • 嗨 skhurams。我想知道是否可以要求您安装英文拼写检查器?另请参阅有关您过去问题的编辑通知,以便您记住此处进行了哪些编辑。特别是(1)I am的缩略为I'm,带有撇号; (2) 指代自己的人称代词“I”总是大写(I, I'm, I'll, I'd)。
  • 这能回答你的问题吗? CEF sharp browser wait till website fully loaded

标签: c# cefsharp cefsharp.offscreen


【解决方案1】:

项目源代码中的CefSharp.OffScreen.Example.Program.cs 类包含使用TaskCompletionSource 包装LoadingStateChanged 事件的示例,因此您可以await Page Load

作为扩展方法实现的基本示例如下所示:

public static class WebBrowserExtensions
{
    public static Task LoadPageAsync(this IWebBrowser browser, string address = null)
    {
        var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);

        EventHandler<LoadingStateChangedEventArgs> handler = null;
        handler = (sender, args) =>
        {
            //Wait for while page to finish loading not just the first frame
            if (!args.IsLoading)
            {
                browser.LoadingStateChanged -= handler;
                //Important that the continuation runs async using TaskCreationOptions.RunContinuationsAsynchronously
                tcs.TrySetResult(true);
            }
        };

        browser.LoadingStateChanged += handler;

        if (!string.IsNullOrEmpty(address))
        {
            browser.Load(address);
        }

        return tcs.Task;
    }
}

然后你可以编写类似的代码

browser = new ChromiumWebBrowser();
await browser.LoadPageAsync(testUrl);

浏览器被编写为async,不推荐也不支持使用Task.Wait 进行阻止。使用async/await

【讨论】:

【解决方案2】:

你必须设置一个标志并等待那个标志。

private bool flag = false;

private void some_function(){

    browser = new ChromiumWebBrowser(); //without testUrl
    browser.Load(testUrl);
    browser.LoadingStateChanged += BrowserLoadingStateChanged;

    while(!flag)
    {
        Thread.Sleep(100);
    }
}
private void LoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
{
    if (!e.IsLoading)
    {
        flag = true;
    }
}

这段代码看起来很无聊。但是你可以封装一个铬浏览器。也许你可以使用单例模式。并实现等待功能。

【讨论】:

  • 说你必须设置一个标志是不正确的,这是一种可能的解决方案,我建议人们尽可能避免。 github.com/cefsharp/CefSharp/blob/cefsharp/75/… github.com/cefsharp/CefSharp/blob/cefsharp/75/… 项目源演示如何将 LoadingStateChanged 包装在 TaskCompletionSource 中。该示例至少需要 .Net 4.6
  • 再次感谢您的关注。请提供正确答案,而不是对此问题的评论。这比批评@amaitland 更有价值
  • 我在stackoverflow.com/a/59276733/4583726 提供了另一种可能的解决方案您的some_function 方法将阻塞它所调用的线程,如果您在UI 线程上执行此操作的次数足够多,您的应用程序可能会对用户无响应输入。这是否更好地解释了这个问题?
猜你喜欢
  • 2017-09-13
  • 2020-04-02
  • 2023-03-26
  • 2012-07-07
  • 1970-01-01
  • 2016-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多