-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wait for EvaluateScriptAsync to complete #983
Comments
Are you trying to make |
Thank you for your reply. |
Long and the short, you've tried to I'd suggest if you must have a helper function that you pass in some for of |
I've tried your first suggestion but I get an aggregate exception on the Wait instruction. The inner exception says "The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state." |
Your code should look like var task = browser.EvaluateScriptAsync(script, timeout);
task.Wait();
var response = task.Result;
result = response.Success ? (response.Result ?? "null") : response.Message;
return result; If your seeing an exception, then your likely causing the |
(Waiting on the |
This sort of question is best asked on something like |
My code looks exactly like yours. Thank you for your time! |
Here is a basic working sample https://gist.github.com/amaitland/7a41cc87b88dfcd30e0e Are you sure the script your evaluating returns a result? You can usually execute your code manually using |
It looks exactly like my code, I don't know why I get the faulted channel exception. If you say that's working for you, I think I have to investigate more on that. |
What script are you executing? Can you confirm something simple works e.g. |
Can you provide a fully functional |
The GIST seems pretty clear the problem is most likely: You want your If you call the GIST code on your UI thread then you probably want: |
Thank you rassilon, Unfortunately I cannot use TaskCreationOptions.HideScheduler because I'm using .NET 4.0 @amaitland I'm preparing the code for you! |
ContinueWith has an overload that can accept Bill |
You're right, I already used it this morning but the issue is still the same. @amaitland You can find my code here: https://gist.github.com/nico87/ea25a6fd18762b97486c |
Oh, |
On the threading side of things code is being called in CEF's |
Just as an FYI: I'm not sure what the code for the WCF proxy looks like for Begin/End pairs. I think that is most likely where any problem is likely to be occurring, since I agree with you the odds of a SyncContext problem from |
I'd still argue that using a |
I think we have two problems here
|
|
The example in the |
Works for me. |
Thank you all for your help. I know that trying to sync the In the coming days I hope to get some other spare time to continue investigating this. Thank you for your time. |
Guys, you know CefSharp better than me. Do you think this may be a CefSharp3 Winforms related issue? Thank you! |
Are you still trying to call |
Nope. I'm calling it from |
Can you fork the |
Hello amaitland, I'm sorry for being so late. I've finally managed to get some spare time to recreate the issue on the Minimal Example Project. Here's my fork: https://github.com/nico87/CefSharp.MinimalExample What I do in the example is a simulation of what I need in my real world usage of CefSharp:
|
To use |
I agree with you but there's a point in my software were I have to wait for the JS result before going on. |
In the following way, this issue has been solved! public BrowserForm()
{
InitializeComponent();
chromiumWebBrowser = new ChromiumWebBrowser("http://google.com") { Dock = DockStyle.Fill };
this.Controls.Add(chromiumWebBrowser);
chromiumWebBrowser.LoadingStateChanged += ChromiumWebBrowser_LoadingStateChanged1;
}
private void ChromiumWebBrowser_LoadingStateChanged1(object sender, LoadingStateChangedEventArgs e)
{
if (e.IsLoading == false) {
Task<CefSharp.JavascriptResponse> response = chromiumWebBrowser.EvaluateScriptAsync("document.getElementById('id').innerHTML");
Func<Task<CefSharp.JavascriptResponse>> func = () =>
{
response.Wait();
return response;
};
func.BeginInvoke((ar) =>
{
var result = func.EndInvoke(ar);
if (result.Result.Result != null)
{
File.AppendAllText("result.txt", result.Result.Result.ToString());
}
},
null);
}
} |
@shenopkss A simple browser.EvaluateScriptAsync("1 + 1").ContinueWith(x =>
{
var response = x.Result;
if (response.Success && response.Result != null)
{
File.AppendAllText("result.txt", response.Result.ToString());
}
}); |
@amaitland 赞!nice! |
@shenopkss, that's not a solution. Your code is running asynchronously while the issue is related to a synchronous execution of EvaluateScript. public object EvaluateScript(string script, object defaultValue, TimeSpan timeout) {
var result = defaultValue;
if (_browser.IsBrowserInitialized && !_browser.IsDisposed && !_browser.Disposing) {
try {
var task = _browser.EvaluateScriptAsync(script, timeout);
var completed = task.ContinueWith(res => {
if (!res.IsFaulted) {
var response = res.Result;
result = response.Success ? (response.Result ?? "null") : response.Message;
}
else {
Console.WriteLine("JS Thread is faulted");
}
});
completed.Wait();
}
catch (Exception e) {
Console.WriteLine(e.InnerException.Message);
}
}
return result;
} Unfortunately, with releases newer than 39.0.2 this code is not working anymore. Therefore I'm still looking for a real solution. |
PS: Is this example supposed to work? https://github.com/cefsharp/CefSharp/blob/master/CefSharp.WinForms.Example/BrowserTabUserControl.cs#L200 |
Probably not, don't think it's ever called. |
That code has been removed with 8de2257 |
Thanks for your efforts. |
I finally managed to solve my synchronization problems with v41+ builds. public class MyBrowser {
private ChromiumWebBrowser _browser;
// Some initialization/constructor code here
// ...
// Sync the async script execution
public async Task<object> EvaluateScript(string script, object defaultValue, TimeSpan timeout) {
object result = defaultValue;
if (_browser.IsBrowserInitialized && !_browser.IsDisposed && !_browser.Disposing) {
try {
var task = _browser.EvaluateScriptAsync(script, timeout);
await task.ContinueWith(res => {
if (!res.IsFaulted) {
var response = res.Result;
result = response.Success ? (response.Result ?? "null") : response.Message;
}
}).ConfigureAwait(false); // <-- This makes the task to synchronize on a different context
}
catch (Exception e) {
Console.WriteLine(e.InnerException.Message);
}
}
return result;
}
} I can use it like this: object result = myBrowser.EvaluateScript("2+2", 0, TimeSpan.FromSeconds(1)).GetAwaiter().GetResult(); |
Hi @nico87 I'd also like to use the "await" but using your code i get the following error: Am I missing something? |
Hi @Anthonidas Is your browser correctly initialized? You should be able to get more information from the exception's stack trace. |
Hi @nico87 |
I'm trying to make public JavascriptResponse EvaluateScript(string script)
{
var response = Task.Run(() => EvaluateScriptAsync(script)).GetAwaiter().GetResult();
if (response.Success)
return response;
throw new EvaluateJSScriptException(response.Message);
}
private async Task<JavascriptResponse> EvaluateScriptAsync(string script)
{
return await _browser.GetMainFrame().EvaluateScriptAsync(script).ConfigureAwait(false);
} It causes deadlock when |
EvaluateScriptAsync is an async function and calling it in a sync fashion is not supported.
.Net supports asynchronous event handlers. There's no need for sync calls. In terms of keyboard/mouse events there are methods for sending those directly to the browser http://cefsharp.github.io/api/85.3.x/html/Methods_T_CefSharp_IBrowserHost.htm You could potentially use DevTools to send input events also
This thread has been inactive for over four years, please use one of the options listed at https://github.com/cefsharp/CefSharp#contact to ask any follow up questions. |
Hi,
I would like to wait for EvaluateScriptAsync to complete but all I get is a deadlock. I think that's because both the script task and the task.Wait() are running in the UI thread.
Is there another way to get this working?
Here's my code: https://gist.github.com/nico87/bf6ba552af8300a06b15
Thank you!
The text was updated successfully, but these errors were encountered: