Problems with offscreen browser events - LoadError - Aborted

1,601 views
Skip to first unread message

toda...@gmail.com

unread,
Feb 20, 2015, 1:01:20 PM2/20/15
to cefs...@googlegroups.com
Hi,

We are trying to use the CefSharp Offscreen Browser to load an HTML file (from memory string) and execute some JavaScript on the DOM to extract some information from the file. We have not been completely successful in getting this to work. We have some issues with synchronization and load errors:

In pseudocode, our code looks like:

// Browser Initialization (once from a class ctor)
CefSettings.RegisterScheme(new CefCustomSceme()
{
   
SchemeName = "myscheme",
   
SchemeHandlerFactory = new MySchemeHandlerFactory()
}


// Event for syncing between the worker threads and the main thread.
ManualResetEvent sync = new ManualResetEvent(false);


// Create new browser and listen for status events
ChromiumWebBrowser browser = new ChromiumWebBrowser();
browser
.FrameLoadEnd += Browser_FrameLoadEnd;
browser
.LoadError += Browser_LoadError;


// Load the HTML document
browser
.LoadHtml("<html>...", "myscheme://web/test/_Mem_Doc_.html")


// Wait for the load to complete! THIS WAITS FOREVER!!!
sync
.WaitOne();


// ... if we ever get here, we'll execute some JavaScript .... and return the result from it.




// Handler for error ... only for diag purposes
Browser_LoadError(object sender, Args e)
{
   
// WE GET A LOAD ERROR !!! We ignore this (if error is Aborted)
    e
.ErrorCode == "Aborted"
    e
.ErrorText == ""
    e
.FailedUrl == "myscheme://web/test/_Mem_Doc_.html"
}
               
Browser_FrameLoadEnd(object sender, Args e)
{
   
// Load ended ... tell the main thread to continue ... SOMETIMES THIS NEVER HAPPENS!
    sync
.Set();
}



The above is basically what our code does. The LoadError is always raised with "Aborted" and our own URL as the failed document. In some scenarios (same document, on one machine always, on other machine often) we don't get the FrameLoadEnd event. Without the FrameLoadEnd event, the main thread will be blocked forever. Our first attempt was to signal the sync event from the LoadError handler and set a flag that the document load has failed. However, since this event is apparently always triggered, that won't help us, so we chose to ignore it.

What are we doing wrong? Is our document always fail to load? Why are we getting the LoadError events? And is the FrameLoadEnd event the correct way to know that the document is ready to process our JavaScript? Or have we completely misunderstood the logic of the Offscreen Browser and need a completely different strategy?

Can someone with knowledge explain why the LoadError / Aborted event is raised?


Thanks!


PS: Below is a stack trace from the Browser_LoadError with the reason for the load error.


> MyApp.Offscreen.exe!MyApp.Offscreen.CefSharpOffScreenHelper.Browser_LoadError(object sender, CefSharp.LoadErrorEventArgs e) Line 135 C#
  CefSharp.OffScreen.dll!CefSharp.OffScreen.ChromiumWebBrowser.CefSharp.Internals.IWebBrowserInternal.OnLoadError(string url, CefSharp.CefErrorCode errorCode, string errorText) Line 466 + 0x2f bytes C#
  CefSharp.Core.dll!CefSharp::Internals::ClientAdapter::OnLoadError(CefRefPtr<CefBrowser>* browser, CefRefPtr<CefFrame>* frame,  errorCode, CefStringBase<CefStringTraitsUTF16>& errorText, CefStringBase<CefStringTraitsUTF16>& failedUrl) Line 172 + 0x3e bytes C++
  CefSharp.Core.dll!load_handler_on_load_error()  + 0x281 bytes
  libcef.dll!CefLoadHandlerCToCpp::OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, cef_errorcode_t errorCode, const CefStringBase<CefStringTraitsUTF16> & errorText, const CefStringBase<CefStringTraitsUTF16> & failedUrl)  Line 113 + 0x3c bytes C++
  libcef.dll!CefBrowserHostImpl::OnLoadError(CefRefPtr<CefFrame> frame, const GURL & url, int error_code, const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > & error_description)  Line 2832 + 0x8b bytes C++
  libcef.dll!CefBrowserHostImpl::DidFailProvisionalLoad(__int64 frame_id, const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > & frame_unique_name, bool is_main_frame, const GURL & validated_url, int error_code, const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > & error_description, content::RenderViewHost * render_view_host)  Line 2385 C++
  libcef.dll!content::WebContentsImpl::DidFailProvisionalLoadWithError(content::RenderFrameHostImpl * render_frame_host, const FrameHostMsg_DidFailProvisionalLoadWithError_Params & params)  Line 2357 + 0xb0 bytes C++
  libcef.dll!content::NavigatorImpl::DidFailProvisionalLoadWithError(content::RenderFrameHostImpl * render_frame_host, const FrameHostMsg_DidFailProvisionalLoadWithError_Params & params)  Line 270 C++
  libcef.dll!content::RenderFrameHostImpl::OnDidFailProvisionalLoadWithError(const FrameHostMsg_DidFailProvisionalLoadWithError_Params & params)  Line 397 C++
  libcef.dll!FrameHostMsg_DidFailProvisionalLoadWithError::Dispatch<content::RenderFrameHostImpl,content::RenderFrameHostImpl,void,void (__thiscall content::RenderFrameHostImpl::*)(FrameHostMsg_DidFailProvisionalLoadWithError_Params const &)>(const IPC::Message * msg, content::RenderFrameHostImpl * obj, content::RenderFrameHostImpl * sender, void * parameter, void (const FrameHostMsg_DidFailProvisionalLoadWithError_Params &)* func)  Line 404 + 0x4b bytes C++
  libcef.dll!content::RenderFrameHostImpl::OnMessageReceived(const IPC::Message & msg)  Line 296 + 0x37 bytes C++
  libcef.dll!content::RenderProcessHostImpl::OnMessageReceived(const IPC::Message & msg)  Line 1416 + 0x7 bytes C++
  libcef.dll!IPC::ChannelProxy::Context::OnDispatchMessage(const IPC::Message & message)  Line 274 C++
  libcef.dll!base::internal::Invoker<2,base::internal::BindState<base::internal::RunnableAdapter<void (__thiscall `anonymous namespace'::SelectFileDialogImpl::*)(A0x9ee13934::SelectFileDialogImpl::ExecuteSelectParams const &)>,void __cdecl(`anonymous namespace'::SelectFileDialogImpl *,A0x9ee13934::SelectFileDialogImpl::ExecuteSelectParams const &),void __cdecl(`anonymous namespace'::SelectFileDialogImpl *,A0x9ee13934::SelectFileDialogImpl::ExecuteSelectParams)>,void __cdecl(`anonymous namespace'::SelectFileDialogImpl *,A0x9ee13934::SelectFileDialogImpl::ExecuteSelectParams const &)>::Run(base::internal::BindStateBase * base)  Line 1253 + 0x9 bytes C++
  libcef.dll!base::MessageLoop::RunTask(const base::PendingTask & pending_task)  Line 452 C++
  libcef.dll!base::MessageLoop::DoWork()  Line 577 C++
  libcef.dll!base::MessagePumpForUI::DoRunLoop()  Line 219 C++
  libcef.dll!base::MessagePumpWin::Run(base::MessagePump::Delegate * delegate)  Line 47 + 0x3d bytes C++
  libcef.dll!base::MessageLoop::RunHandler()  Line 400 + 0x9 bytes C++
  libcef.dll!base::RunLoop::Run()  Line 50 C++
  libcef.dll!base::MessageLoop::Run()  Line 294 C++
  libcef.dll!base::Thread::Run(base::MessageLoop * message_loop)  Line 173 C++
  libcef.dll!base::Thread::ThreadMain()  Line 229 C++
  libcef.dll!base::`anonymous namespace'::ThreadFunc(void * params)  Line 80 C++
  kernel32.dll!@BaseThreadInitThunk@12()  + 0x24 bytes
  ntdll.dll!__RtlUserThreadStart()  + 0x2f bytes
  ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes

Alex Maitland

unread,
Feb 20, 2015, 7:34:10 PM2/20/15
to cefs...@googlegroups.com
Where is your call to `Cef.Initialize`?

toda...@gmail.com

unread,
Feb 20, 2015, 8:26:20 PM2/20/15
to cefs...@googlegroups.com
It's there (at the very beginning as part of the initialization). It just got lost while reducing the real code to pseudocode to remove unnecessary complexity.

Alex Maitland

unread,
Feb 20, 2015, 8:34:20 PM2/20/15
to cefs...@googlegroups.com
Can you fork https://github.com/cefsharp/CefSharp.MinimalExample and upload your sample to github. Psudo code in a case like this doesn't really help accurately reproduce the problem.

Also does your code work if you just use a normal url e.g. www.google.com.au? The OffScreen project is in it's infancy and as such only a small number of scenarios have been tested.

toda...@gmail.com

unread,
Feb 23, 2015, 11:50:48 AM2/23/15
to cefs...@googlegroups.com
HI Alex!
It took a while but we've finally created a test case. We've forked thew minimal example as suggested and I've just committed the test case. You'll find it here: https://github.com/derroman/CefSharp.MinimalExample 


It is basically what we described in the mail before as pseudo code. You'll find a little for loop with 15 iterations.

We get this aborted error we've described before and in addition on a slower machine the whole program freezes after some iterations. 

Hopefully you could reproduce this and have some ideas on how to fix this.

Alex Maitland

unread,
Feb 24, 2015, 6:49:38 AM2/24/15
to cefs...@googlegroups.com
I've created a PR for your github repository, see https://github.com/derroman/CefSharp.MinimalExample/pull/1

Basically most of the issues your experience are resolved by upgrading to the latest CI build. I plan to release a new `-pre` package for the `39` release shortly, so I'd suggest upgrading to that.

There's only a handful of outstanding issues left before the official release. The CI builds are now based on the latest official CEF release, so it should be pretty much production ready (I know quite a few who are already using it in production).

Let me know how you go.
Reply all
Reply to author
Forward
0 new messages