Deadlocks when using both RegisterJsObject and EvaluateScript

732 views
Skip to first unread message

Marcin Wiśnicki

unread,
Sep 13, 2012, 7:41:26 PM9/13/12
to cefs...@googlegroups.com

I need to communicate in both directions in response to various events happening independently in browser and in WPF (but I'm using CefSharp.WinForms).

Unfortunately quite often browser and wpf try to perform the call at the same time which results in deadlock or a timeout exception (if specified in a call to EvaluateScript).

How can I protect against such situations ?

anthony taranto

unread,
Sep 13, 2012, 8:00:58 PM9/13/12
to cefs...@googlegroups.com
From your description, it is not clear to me what the problem is. You may be interested in this pull request, which will add the ability to call CLR methods from js executed by CefSharp. Alternatively, you might try to implement a mechanism to ensure that your calls occur sequentially.

What is the reason that you have chosen to use the WinForms control in your WPF app?

Marcin Wiśnicki

unread,
Sep 14, 2012, 3:31:10 AM9/14/12
to cefs...@googlegroups.com
Any attempt at solving it with lock object, either in .net or js would
still result in deadlock:
0. assume a lock object in .net is exposed with RegisterJsObject("lock")
1. javascript calls lock.lock()
2. lock() enters CefSharp code but does not yet reach actual lock() method
3. at the same time host acquires still not claimed lock
4. and proceeds to perform call to EvaluateScript
6. but since javascript code already entered CefSharp code it gets
blocked somewhere and nothing can continue

Only ways that I could solve it is either using short timeouts and
retrying until success or not using EvaluateScript and instead
simulate it using message queue and polling from browser (like ajax)
but both seem ugly and complicate things greatly (have to make
everything async).

I'll try to make a simple reproducible testcase later. It should be
enough to perform repeated calls in both directions with short
interval.

I'm using WinForms control because I need to do drag and drop and it
isn't working in Wpf (not even inside the browser).
> --
> You received this message because you are subscribed to the Google Groups
> "CefSharp" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/cefsharp/-/_Tacmg17UBUJ.
> To post to this group, send email to cefs...@googlegroups.com.
> To unsubscribe from this group, send email to
> cefsharp+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/cefsharp?hl=en.

Marcin Wiśnicki

unread,
Sep 14, 2012, 3:40:21 AM9/14/12
to cefs...@googlegroups.com
On Fri, Sep 14, 2012 at 2:00 AM, anthony taranto
<anthony...@gmail.com> wrote:
> From your description, it is not clear to me what the problem is. You may be
> interested in this pull request, which will add the ability to call CLR
> methods from js executed by CefSharp.

If by "this" you mean #86 then that would require me to make my code
asynchronous (something I would like to avoid) ?

Jack O'Connor

unread,
Sep 14, 2012, 4:27:09 AM9/14/12
to cefs...@googlegroups.com
I'll give the same advice I've given elsewhere, which is that you should make sure you're not calling Execute/EvaluateScript from anything other than the UI thread. I don't think there's anything inherently bad about JS calling into C# while other C# code is running. The problems I've had come from hitting the WinForms controls themselves from more than one thread. In particular, calls made from JS to the methods exposed by RegisterJSObject are running on the JS thread, not the UI thread. If any of those calls end up calling back to EvaluateScript without BeginInvoke()ing onto the UI thread, that could break CefSharp in the way you're experiencing.

--
You received this message because you are subscribed to the Google Groups "CefSharp" group.

Marcin Wiśnicki

unread,
Sep 14, 2012, 5:53:57 AM9/14/12
to cefs...@googlegroups.com
I marshall all incoming and outgoing calls to ui thread via dispatcher
but the problem happens somewhere in CefSharp when both javascript and
.net enter Cef at the same time.

anthony taranto

unread,
Sep 14, 2012, 2:04:03 PM9/14/12
to cefs...@googlegroups.com
Well, it seems like enough people are hitting this that we might have
to look into actually making the CefSharp API threadsafe.
Message has been deleted

Rob Christ

unread,
Apr 4, 2014, 2:11:28 PM4/4/14
to cefs...@googlegroups.com
First of all, does anyone know if this is resolved in cef 3?

anthony, Jack, I don't believe that to be the problem.  I am currently using cefsharp 1.x stable.  In my implementation, I have done the following things:

A thread (we'll say thread 1), news up a WebView control.  This thread sets various methods to the events available on WebView.  It additionally sets up Js callback method.  Thread 1 then occasionally calls WebView.EvaluateScript to figure out what the user is doing.  Just to be extra safe, I've wrapped the webview object in a class, and used a locking object to ensure that no matter what is going on in my code, EvaluateScript is only called by one thread at a time.

When the exposed javascript method is called, it crunches some data, and pushes the results to an, as of currently, unused object elsewhere in the program.  Nothing else.

Now when the page is finished loading, as triggered by WebView.LoadCompleted, I set a script on the document that is supposed to (it doesn't seem to work, but) call the exposed javascript method whenever the user scrolls.  Interestingly, I've found that all of the WebView events are raised on a different thread than the thread I initiated the webview object with, so I've tested the following with both that thread, and thread 1.

In my experience, if I go to a website, and scroll, occasionally, a call to EvaluateScript by Thread1 will timeout, or lockup, depending on whether a timeout value is specified. Indeed, it seems that even if a timeout/exception isn't raised, so long as thread 1 is occasionally calling evaluate script, the registered callback method may not be called with any consistency.

After reading Jack's post, I thought that perhaps the problem is the fact that there were conflicting threads.  As such, I tested calling evaluate script with both Thread1, and the thread created when WebView's events are raised, but both have the same problem.  

I have no way, that I can tell, of calling evaluate script with the thread that calls the exposed javascript method.  I tried such craziness as WebView.Invoke(Webview.EvaluateScript), but as expected, that was not successful.

So I think the problem must be that within cef or cefsharp, my Thread1 will call EvaluateScript while CefSharp's javascript thread attempts to call the exposed javascript method, or vice versa, and as a result, the exposed method is not called, and the evaluate script call times out or locks up.

-Rob

Rob Christ

unread,
Apr 4, 2014, 2:14:45 PM4/4/14
to cefs...@googlegroups.com
As an aside, I just noticed that this thread has >300 views, so clearly this has been a concern to quite a few people : )

Rob Christ

unread,
Apr 8, 2014, 4:43:25 PM4/8/14
to cefs...@googlegroups.com
For anyone following along, I'm going to just stop using the js callback entirely, because thankfully there's keydown and onmousescroll events available.  Until I realized this, I was going to replace jscallbacks entirely, by setting up a thread dispatcher that would regularly call evaluateScript.

Hopefully we can get this better working in cef3, invoke script has a series of problems as well.

Rob
Reply all
Reply to author
Forward
0 new messages