2016-11-02 1 views
2

Wie kann ich eine .NET-async-Methode von JS in CefSharp aufrufen. Ich möchte eine Methode aufrufen, die auf einen Konsolenanwendungsaufruf wartet.Async-Methode von JS in CefSharp aufrufen

Meine Idee ist folgende: ich eine Methode, mit der Unterschrift unter aufrufen:

public async Task<int> Calculate(){ 

und wenn es fertig ist, dann wird das Ergebnis durch ein Versprechen auf der JS Seite zurück gegeben. Momentan funktioniert es nicht. Wenn es fertig ist, gibt es keinen Rückruf und ich kann es nicht mehr aufrufen.

Vielen Dank

Antwort

2

Ich stieß auf das gleiche Problem.

Eine hässliche Abhilfe scheint Ihre Methode async void und akzeptieren zwei IJavascriptCallback Argumente (resolve und reject) zu mangeln.

Zum Beispiel:

public class MyCalculator 
{ 
    public async void CalcAsync(
     string name, 
     IJavascriptCallback resolve, 
     IJavascriptCallback reject) 
    { 
     try 
     { 
      if (resolve.IsDisposed) 
       return; 

      int i = /* compute i */; 

      if (!resolve.IsDisposed) 
       await resolve.ExecuteAsync(i); 
     } 
     catch (Exception e) 
     { 
      if (!reject.IsDisposed) 
       await reject.ExecuteAsync(e.ToString()); 
     } 
    } 
} 

Angemeldet als:

browser.RegisterAsyncJsObject("myCalculator", new MyCalculator()); 

Dann in Ihrem JavaScript:

function doThingAsync(name) { 
    return new Promise(function (resolve, reject) { 
     window.myCalculator.calcAsync(name, resolve, reject); 
    }); 
} 

var result = await doThingAsync("foo") 

Sie können das Muster herausziehen als so etwas wie:

private static async Task Promisify(IJavascriptCallback resolve, IJavascriptCallback reject, Func<Task> action) 
{ 
    try 
    { 
     if (!resolve.IsDisposed) 
      await action(); 

     if (!resolve.IsDisposed) 
      await resolve.ExecuteAsync(); 
    } 
    catch (Exception e) 
    { 
     if (!reject.IsDisposed) 
      await reject.ExecuteAsync(e.ToString()); 
    } 
} 

private static async Task Promisify<T>(IJavascriptCallback resolve, IJavascriptCallback reject, Func<Task<T>> action) 
{ 
    try 
    { 
     var result = default(T); 

     if (!resolve.IsDisposed) 
      result = await action(); 

     if (!resolve.IsDisposed) 
      await resolve.ExecuteAsync(result); 
    } 
    catch (Exception e) 
    { 
     if (!reject.IsDisposed) 
      await reject.ExecuteAsync(e.ToString()); 
    } 
} 

Die Verfahren würden das gebundene Objekt dann ähneln:

public class MyCalculator 
{ 
    public async void CalcAsync(
     string name, 
     IJavascriptCallback resolve, 
     IJavascriptCallback reject) 
    { 
     Promisify(resolve, reject,() => /* compute i */); 
    } 
} 

Die (hypothetische) API Ich würde ähneln verwenden möchten:

public class MyCalculator 
{ 
    public async Task<int> CalcAsync(string name) => /* compute i */; 
} 

Und:

var result = await window.myCalculator.calcAsync("foo") 
Verwandte Themen