在JavaScript中使异步事件同步

时间:2009-02-06 02:24:46

标签: c# javascript wpf

我正在使用WPF 3.5SP1 WebBrowser控件来显示包含一些javascript函数的页面。 然后我的程序需要调用一个javascript函数来进行异步调用。我需要一种方法将异步调用的结果返回给C#,以便我可以处理结果。

有没有办法可以让第一个javascript函数睡眠,直到出现问题(没有锁定浏览器)?

编辑:我已经在回调了 - 第二个函数实际上被称为“some-async-function-complete”。异步事件结束时调用它。现在我需要一种方法将结果输入C#。

进一步澄清: C#

var result = WebBrowser.InvokeScript("myscript")

的JavaScript

var result;

function myscript()
{
some-async-function();
/* what goes here? */
/* wait until result != null */
return result;
}

function some-async-function-complete(retval)
{
result = retval;
}

5 个答案:

答案 0 :(得分:4)

  

有没有办法让我做第一个   javascript函数睡到   事情发生了(没有锁定   浏览器)?

是的 - 您可以使用异步函数,因为它打算使用它:传递一个回调函数,并让它做它的事情。您应该能够将来自C#的回调传递给您的JS函数,然后可以将其直接传递给异步函数,或者如果需要进行后处理,则将其包装在另一个函数中。


回调实现的一个例子 - 这适用于WinForms WebBrowser控件,我没有用WPF测试它,但它们应该完全一样:

[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class Callback
{
   // allows an instance of Callback to look like a function to the script
   // (allows callback() rather than forcing the script to do callback.callMe)
   [System.Runtime.InteropServices.DispId(0)]
   public void callMe(string url)
   {
      // whatever you want to happen once the async process is complete
   }
}

...

Callback cb = new Callback();
WebBrowser.InvokeScript("myscript", new object[] { cb })

...

function myscript(callback)
{
   some_async_function(function()
   {
      // script-specific completion code
      if ( callback )
         callback();
   });
}

答案 1 :(得分:2)

请参阅相关问题:Can you wait for javascript callback?

引用my answer中的引文到该问题:

  

JavaScript Strands增加了协程和   合作线程支持   JavaScript语言启用阻止   异步事件的功能   回调。

还有更多:

  

Narrative JavaScript很小   JavaScript语言的扩展   这使得阻止功能成为可能   异步事件回调。这个   令人兴奋的异步代码   可读和易懂。

虽然在技术上可以使通常异步代码表现为同步,但我建议您重新考虑您的设计以采用异步方法。

答案 2 :(得分:0)

如果我正确地阅读了这个问题,那么你正在寻找一个回调......例如......

function myscript()
{
    some-async-function(
        params, //any params you plan to use
        function(result) {
           //handle the result here
        });
}

function some-async-function(retval,callback)
{
    //assuming this really is an async function such
    //as an ajax call, etc...
    ...

    //work done, use the call back
    callback(retval);

}

答案 3 :(得分:0)

您可能会将自己的应用视为桌面应用。您的C#程序未连接到任何要同步的程序。相移到网络模式的时间。

你可以来的最近的是javascript回调调用ajax,用于与主机的另一次交换。

答案 4 :(得分:0)

  

有没有办法可以让第一个javascript函数睡眠,直到出现问题(没有锁定浏览器)?

在您希望它工作的方式中,没有。

需要AFAIK,线程控制或连续循环 - 第一个在JavaScript中不可用,而后者将锁定大多数浏览器。

我认为您需要使用Ajax(来自result)将JavaScript some-async-function-complete发送到服务器。然后,分解您的C#以进行一部分调用myscript,另一部分回复并处理result