tags:

views:

1159

answers:

5

I'm using the WPF 3.5SP1 WebBrowser control to display a page containing some javascript functions. My program then needs to invoke a javascript function which will make an asynchronous call. I need a way to get the result of that asynchronous call back to C# so I can process the result.

Is there a way I can make the first javascript function sleep until something happens (with out locking up the browser)?

edit: I am already using a call back - the 2nd function is actually called "some-async-function-complete". It gets called when the async event finishes. Now I need a way to get the result into C#.

For further clarification: 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;
}
+1  A: 

Is there a way I can make the first javascript function sleep until something happens (with out locking up the browser)?

Yes - you can use the asynchronous function as it was intended to be used: pass it a callback, and let it do its thing. You should be able to pass a callback from C# into your JS function, which can then either pass it to your asynchronous function directly, or wrap it in another function if post-processing is required.


An example of the implementation of a callback - this works with the WinForms WebBrowser control, i haven't tested it with WPF but they should be pretty much the same:

[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();
   });
}
Shog9
Can you elaborate on how I can pass a callback from C# into JS?
vanja.
ok - quick'n'dirty example
Shog9
Sweet, this looks like it will work. Hopefully WPF doesn't mess things up. Thanks again.
vanja.
A: 

If I'm reading the question correctly, you're looking for a callback... so for example...

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);

}
Hugoware
I am already using a call back - the 2nd function is actually called "some-async-function-complete". It gets called when the async event finishes. Now I need a way to get the result into C#
vanja.
A: 

You're possibly thinking of your app as a desktop app. Your C# program isn't connected to anything to be synchronous with. Time for a phase-shift into web-mode.

The closest you can come is have the javascript callback call ajax for another interchange with the host.

le dorfier
My C# program is a desktop app :P I'm running the JavaScript inside a WPF WebBrowser control. Event's are sent with WebBrowser.InvokeScript()
vanja.
It's getting complicated, because I'm not sure about what the goal is. But the WebBrowser control presumably needs to POST or GET or Ajax something to a host somewhere to continue the process. It doesn't know about your C# program I don't think; but I've never used that control.
le dorfier
A: 

Is there a way I can make the first javascript function sleep until something happens (with out locking up the browser)?

In the way that you're expecting it to work, no.

AFAIK, thread control or continuous looping are needed -- the first is unavailable in JavaScript and the latter will lock up most browsers.

I think you'll need to have JavaScript send result to the server with Ajax (from some-async-function-complete). Then, break up your C# to have one part call myscript and another respond and process result.

Jonathan Lonowski
+1  A: 

See related question: Can you wait for javascript callback?

Quoting from a quote in my answer to that question:

JavaScript Strands adds coroutine and cooperative threading support to the JavaScript language to enable blocking capabilities for asynchronous event callbacks.

And more:

Narrative JavaScript is a small extension to the JavaScript language that enables blocking capabilities for asynchronous event callbacks. This makes asynchronous code refreshingly readable and comprehensible.

Although making normally asynchronous code behave as synchronous is technically possible, I would recommend that you reconsider your design to go with an asynchronous approach.

Ates Goral