How can I invoke an .NET async method from JS in CefSharp. I'd like to invoke a method that waits for a console application call.
My idea is the following: I invoke a method with the signature below:
public async Task<int> Calculate(){
and when it's finished then its result is given back by a promise on the JS side. Currently, it doesn't work. When it's finished there is no callback and then I'm not able to invoke it again.
Thank you
I came up against the same issue.
An ugly workaround seems to be mangling your method to async void and accepting two IJavascriptCallback arguments (resolve and reject).
For example:
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());
}
}
}
Registered as:
browser.RegisterAsyncJsObject("myCalculator", new MyCalculator());
Then in your JavaScript:
function doThingAsync(name) {
return new Promise(function (resolve, reject) {
window.myCalculator.calcAsync(name, resolve, reject);
});
}
var result = await doThingAsync("foo")
You can pull the pattern out as something like:
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());
}
}
The bound object's methods would then resemble:
public class MyCalculator
{
public async void CalcAsync(
string name,
IJavascriptCallback resolve,
IJavascriptCallback reject)
{
Promisify(resolve, reject, () => /* compute i */);
}
}
The (hypothetical) API I'd like to use would resemble:
public class MyCalculator
{
public async Task<int> CalcAsync(string name) => /* compute i */;
}
And:
var result = await window.myCalculator.calcAsync("foo")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With