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