Всем привет! Сегодня мы продолжим говорить о работе с управляемым кодом при разработке Windows Store JavaScript приложений. В прошлой статье мы познакомились с ограничениями проекта Windows Runtime Component и рассмотрели самый простой пример вызова функции на C#.
В этой статье мы, в первую очередь, рассмотрим асинхронные вызовы между JavaScript и C#, которые де-факто являются основой взаимодействия с управляемым кодом. А также узнаем, как можно передавать сложные типы данных между вызовами, научимся использовать события и отлаживать наш код в Visual Studio.
Асинхронный вызов функций
Стоит отметить, что использовать какие-либо вызовы кроме асинхронных строго не рекомендуется. В принципе, в любом клиентском приложении (JS, Silverlight, WinForms) выполнение тяжелых операций в главном потоке ведет к снижению производительности и в конечном счете зависанию клиентского приложения.
Ниже приведен код класса в проекте Windows Runtime Component, который предоставит клиенту всего один метод:
1: public sealed class ManagementClass
2: {
3: public IAsyncOperation<string> GetHelloMessageAsync(string name)
4: {
5: return Task.Run(async () => await StartTask(name)).AsAsyncOperation();
6: }
7:
8: private Task<string> StartTask(string name)
9: {
10: return Task.Factory.StartNew(() => GetHelloString(name));
11: }
12:
13: private string GetHelloString(string name)
14: {
15: return "Hello " + name;
16: }
17: }
То есть, для каждого метода, который вы будете использовать на стороне WinJS необходимо написать три метода на C# для правильного «асинхронного» вызова. Согласитесь, немного накладно. Но, что делать, пока это единственный способ. Платформа и средства разработки появились сравнительно недавно, поэтому я уверен в следующих версиях мы увидим способы более удобного использования.
Пример вызова асинхронного метода клиентом приведен ниже:
1: var myClass = new WinJsDemo.Utilities.ManagementClass();
2: myClass.getHelloMessageAsync("Jack").then(
3: function (response) {
4: document.getElementById("content").innerHTML = response;
5: }
6: );
Передача сложных типов данных
Возможности классов сильно ограничены. Параметры функций и тип возвращаемого значения должны быть определены в библиотеке Windows Runtime. То есть, использовать можно только стандартные типы данных и коллекции этих типов соответственно. При передачи коллекций и простых типов из C# кода они будут автоматически преобразованы в соответствующие типы JavaScript. Схема преобразований основных типов приведена в таблице ниже:
Windows Runtime | .NET Framework |
---|---|
IIterable<T> | IEnumerable<T> |
IVector<T> | IList<T> |
IVectorView<T> | IReadOnlyList<T> |
IMap<K, V> | IDictionary<TKey, TValue> |
IMapView<K, V> | IReadOnlyDictionary<TKey, TValue> |
IKeyValuePair<K, V> | KeyValuePair<TKey, TValue> |
При разработке сложных приложений было бы удобно использовать собственные классы для передачи данных между средами. К сожалению, единственный способ это сделать – сериализовать класс в JSON строку и десериализовать строку при получении. На стороне JavaScript существуют методы JSON.parse и JSON.stringify, выполняющие функции сериализации, а вот в C# придется писать все самому, потому что подключить существующие библиотеки для работы с JSON к проекту, увы, не получится.
При разработке сложных приложений было бы удобно использовать собственные классы для передачи данных между средами. К сожалению, единственный способ это сделать – сериализовать класс в JSON строку и десериализовать строку при получении. На стороне JavaScript существуют методы JSON.parse и JSON.stringify, выполняющие функции сериализации, а вот в C# придется писать все самому, потому что подключить существующие библиотеки для работы с JSON к проекту, увы, не получится.
Использование событий
Одна из интересных особенностей, доступных при использовании управляемого кода – поддержка событий. Мы можем объявить событие в C# классе и подписать JavaScript функцию на это событие. Код на стороне C#:
1: public sealed class ManagementClass
2: {
3: public event EventHandler<MyEventArgs> TestEvent;
4:
5: public void RaiseEvent(string value)
6: {
7: if (TestEvent != null)
8: TestEvent(this, new MyEventArgs { Value = value });
9: }
10: }
11:
12: public sealed class MyEventArgs
13: {
14: public string Value { get; set; }
15: }
Класс MyEventArgs помогает нам передавать собственные параметры события подписчикам. Обратите внимания, что его не нужно наследовать от EventArgs, как мы привыкли в обычном C#. Теперь посмотрим на использование события клиентом:
1: var myClass = new WinJsDemo.Utilities.ManagementClass();
2:
3: myClass.addEventListener("testevent", function (eventArgs) {
4: document.getElementById("content").innerHTML = eventArgs.value;
5: });
6: myClass.raiseEvent("Hello from event!");
Заметьте, что имя события переводится в нижний регистр. Впрочем, как и первый символ в имени всех методов.
Исключения и отладка управляемого кода
Объявлять и выбрасывать собственные исключения запрещено. Если модуль не перехватывает исключение – оно будет передано на сторону JavaScript и выброшено там. Стек трейс исключения будет доступен в объекте, перехваченным в блоке try-catch.
Visual Studio также предоставляет возможность отлаживать управляемый код в WinJS приложении. К сожалению, устанавливать точки остановки на стороне C# и на стороне JavaScript одновременно не возможно, только что-то одно. Переключаться между режимами отладки можно в свойствах проекта WinJS (Script Only / Management Only):
Спасибо за внимание. Надеюсь эта статья поможет вам полностью разобраться в аспектах использования управляемого кода при написании JavaScript приложений для Windows 8. Полезные ссылки по теме вы найдете ниже.
Комментариев нет:
Отправить комментарий