Как я могу выполнить функцию обратного вызова Javascript из хост-приложения C #

Я создаю приложение на C #, которое размещает пользовательские веб-страницы для большей части GUI. Как хост, я хотел бы предоставить API javascript, чтобы встроенные веб-страницы могли получать доступ к некоторым услугам, предоставляемым хост-приложением.

Я смог получить простой пример для этой работы, используя свойство WebBrowser.ObjectForScripting и реализуя класс сценариев. Это прекрасно работает для синхронных вызовов JavaScript. Тем не менее, некоторые из операций, которые предоставляет хост, долго выполняются, и я хотел бы предоставить возможность вызова javascript после завершения операции. И вот тут у меня проблемы.

Javascript:

function onComplete( result )
{
    alert( result );
}

function start()
{
    window.external.LongRunningProcess( 'data', onComplete );
}

C #:

[ComVisible(true)]
public class ScriptObject
{
    public void LongRunningProcess( string data, <???> callback )
    {
        // do work, call the callback
    }
}

Функция «start» в javascript запускает весь этот процесс. У меня проблема в том, что тип для обратного вызова? И как мне это назвать из C #?

Если я использую строковый тип для обратного вызова, он компилируется и запускается, но внутри обратного вызова метода LongRunningProcess фактически содержится полное содержимое функции onComplete (т. Е. 'Функция onComplete (result) {alert (result)}')

Если я использую тип объекта, он возвращается как объект COM. Используя метод Microsoft.VisualBasic.Information.TypeName, он возвращает «JScriptTypeInfo». Но, насколько я могу судить, это не настоящий тип, и нет никакого реального упоминания об этом через все MSDN.

Если я использую интерфейс IReflect, он запускается без ошибок, но в объекте, который я могу найти, нет элементов, полей или свойств.

Обходным путем будет передача строкового имени функции обратного вызова вместо самой функции (то есть window.external.LongRunningProcess ('data', 'onComplete');). Я знаю, как выполнить функцию javascript по имени, но я бы предпочел, чтобы этот синтаксис не требовался на веб-страницах, он также не будет работать с определениями встроенного обратного вызова в javascript.

Есть идеи?

Что бы это ни стоило, у меня уже есть эта система, работающая с платформой Chromium Embedded, но я работаю над переносом кода на элемент управления WebBrowser, чтобы избежать огромного размера перераспределения Chromium. Однако разрабатываемые HTML-страницы в конечном итоге будут работать на Linux / Mac OSX, где Chromium, вероятно, все еще будет использоваться.

Ответы на вопрос(2)

Ваш ответ на вопрос