码迷,mamicode.com
首页 > 编程语言 > 详细

cefsharp 关于C# 调用JavaScript的一个坑

时间:2017-09-26 16:15:08      阅读:652      评论:0      收藏:0      [点我收藏+]

标签:lex   which   returns   tostring   一点   func   this   target   world   

之前开发的一个产品在上线后总有奇怪的BUG,经过一番调试后发现在使用CEF控件的

EvaluateScriptAsync

这个方法的时候,并不能保证成功.

经过一番查询,发现官方文档(https://github.com/cefsharp/CefSharp/wiki/General-Usage#devtools)有这么一段

2. How do you call a JavaScript method that returns a result?

If you need to evaluate code which returns a value, use the Task<JavascriptResponse> EvaluateScriptAsync(string script, TimeSpan? timeout) method. JavaScript code is executed asynchronously and as such uses the .Net Task class to return a response, which contains error message, result and a success (bool) flag.

// Get Document Height
var task = frame.EvaluateScriptAsync("(function() { var body = document.body, html = document.documentElement; return  Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight ); })();", null);

task.ContinueWith(t =>
{
    if (!t.IsFaulted)
    {
        var response = t.Result;
        EvaluateJavaScriptResult = response.Success ? (response.Result ?? "null") : response.Message;
    }
}, TaskScheduler.FromCurrentSynchronizationContext());

For a more detailed example check out this Gist

Notes

  • Scripts are executed at the frame level, and every page has at least one frame (MainFrame)
  • Only trivial values can be returned (like int, bool, string etc) - not a complex (user-defined) type which you have defined yourself. This is because there is no (easy) way to expose a random JavaScript object to the .NET world, at least not today. However, one possible technique is to turn the JavaScript object you wish to return to your .NET code into a JSON string with the JavaScript JSON.toStringify() method and return that string to your .NET code. Then you can decode that string into a .NET object with something like JSON.NET. See this MSDN link for more information. (https://msdn.microsoft.com/en-us/library/ie/cc836459(v=vs.94).aspx)

可以用这种方式获取到JS的返回值:

1 task.ContinueWith(t =>
2 {
3     if (!t.IsFaulted)
4     {
5         var response = t.Result;
6         EvaluateJavaScriptResult = response.Success ? (response.Result ?? "null") : response.Message;
7     }
8 }, TaskScheduler.FromCurrentSynchronizationContext());

于是利用这一点,做了个"流水ID"

每次调用的时候就+1,另一头代码执行完后,返回该ID,如果调用失败(或者返回的ID无法识别),则重新发起,如果另一头收到连续两次一样的ID,则不做处理(但还是要返回ID的.).

这样个方法也能用来解决某些丢包问题.

cefsharp 关于C# 调用JavaScript的一个坑

标签:lex   which   returns   tostring   一点   func   this   target   world   

原文地址:http://www.cnblogs.com/DragonStart/p/7596743.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!