0

I'm working on Cefsharp Offscreen in my application. The code provided in documentation to load page is:

 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();

but I want something like that

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

I couldn't find any solution.

amaitland
  • 4,073
  • 3
  • 25
  • 63
skhurams
  • 2,133
  • 7
  • 45
  • 82
  • Hi skhurams. I wonder if I could request that you install an English spelling checker? Please also see the edit notifications on your past questions, so you can remember what sort of edits are made here. In particular (1) the contraction of `I am` is `I'm`, with an apostrophe; (2) the personal pronoun "I" to refer to yourself is always a capital (I, I'm, I'll, I'd). – halfer Oct 05 '19 at 11:43
  • Does this answer your question? [CEF sharp browser wait till website fully loaded](https://stackoverflow.com/questions/42978669/cef-sharp-browser-wait-till-website-fully-loaded) – Deniz May 28 '20 at 18:19

2 Answers2

4

The CefSharp.OffScreen.Example.Program.cs class in the project source contains an example of using a TaskCompletionSource to wrap the LoadingStateChanged event so you can await the Page Load.

A basic example implemented as an extension method would look like:

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;
    }
}

You can then write code like

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

The browser is written to be async and blocking using Task.Wait is not recommended nor supported. Use async/await.

amaitland
  • 4,073
  • 3
  • 25
  • 63
  • 1
    There is now a built in method see http://cefsharp.github.io/api/95.7.x/html/M_CefSharp_IWebBrowser_LoadUrlAsync.htm The built in version has better handling of page load errors. – amaitland Dec 01 '21 at 07:20
  • What about waiting load after form submit button submit on loaded page? – Furkan Gözükara Dec 07 '22 at 14:46
0

You have to set a flag and waiting for that flag.

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;
    }
}

This code looks boring. But you can encapsulate a chromium browser. Maybe you can use singleton pattern. And implement wait function.

devcrazy
  • 505
  • 5
  • 14
  • 2
    Saying you have to set a flag is incorrect, this is one possible solution, one I'd suggest people avoid wherever possible. https://github.com/cefsharp/CefSharp/blob/cefsharp/75/CefSharp.OffScreen.Example/Program.cs#L68 https://github.com/cefsharp/CefSharp/blob/cefsharp/75/CefSharp.OffScreen.Example/Program.cs#L117 The project source demos how to wrap LoadingStateChanged in a TaskCompletionSource. The example requires a minimum of .Net 4.6 – amaitland Dec 10 '19 at 20:15
  • Thank you again for your kind attention. Please provide a correct answer not a comment for this question. It's worthy than criticism @amaitland – devcrazy Dec 11 '19 at 06:11
  • 1
    I have provided another possible solution at https://stackoverflow.com/a/59276733/4583726 Your `some_function` method will block the thread it's called on, if you do this enough times on the `UI` thread your application may become unresponsive to user input. Do this explain the problem a little better? – amaitland Dec 11 '19 at 06:21
  • @amaitland how to properly wait after form submit loading? – Furkan Gözükara Dec 07 '22 at 14:47