Открыть список
Как стать автором
Обновить
14
Карма
0
Рейтинг
Вячеслав Волков @VVS0205

Пользователь

Работаем с Xamarin: опыт разработки на двух проектах

Вы можете использовать MugenMvvmToolkit, проект полностью кроссплатформенный и поддерживает все основные мобильные платформы, у него много плюсов в сравнении с MVVMCross, например:
Недоразумение вызывает лишь реализация передачи параметров во время навигации на другую страницу. Для этого требуется, чтобы класс параметров состоял из свойств простых типов (int, bool, string), т.к. он потом сериализуется в URL.

Используя MugenMvvmToolkit вы можете передавать любые параметры, потому что вы сами создаете ViewModel:
Пример навигации
using (var editorVm = GetViewModel<ProductEditorViewModel>())            
{
   var productModel = new ProductModel { Id = Guid.NewGuid() };
   editorVm.InitializeEntity(productModel, true);
   if (!await editorVm.ShowAsync())
       return;
   //Code that will be called after the completion of navigation, and yes, this code will be executed even if the application had been tombstoned and then restored.
}


Документации пока мало, но есть много примеров, также у нас есть группа на Slack, где вы можете задавать любые вопросы по проекту, ссылка на github.

Сахарные инжекции в C#

Чтобы избежать упаковки, советую заменить:
if (Equals(field, value))

на:
if (EqualityComparer<T>.Default.Equals(field, value))

MugenMvvmToolkit — кроссплатформенный MVVM фреймворк

1) У вас есть что-то готовое для списков?

Поддержка для списков есть на всех платформах. В MVVMCross для этого используются свои контролы, MugenMvvmToolkit использует присоединяемые свойства для стандартных контролов.
Свойтсво ItemsSource, ItemTemplate и ItemTempateSelector для Android поддерживают следующие контролы: ViewGroup(ListView, Spinner, LinearLayout), TabHost, RecyclerView, ViewPager, ActionBar, IMenu.
Пример Binding для ItemsSource
  <ListView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    pkg:ItemTemplate="@layout/_productlisttemplate"
    pkg:Bind="ItemsSource GridViewModel.ItemsSource; SelectedItem GridViewModel.SelectedItem; ScrollToSelectedItem true" />


Кроме, того есть поддержка DataTemplateSelector (аналог DataTemplateSelector для Xaml).
На Android за это отвечают интерфейсы IDataTemplateSelector и IResourceDataTemplateSelector, вы можете использовать более сложную логику для выбора шаблона:
Пример
public class ListItemTemplateSelector : ResourceDataTemplateSelectorBase<ListItemModel>
{
	public override int TemplateTypeCount
	{
		get { return 2; }
	}
	
	protected override int SelectTemplate(ListItemModel item, object container)
	{
		if (item.IsValid)
		   return Resource.Layout._ListItemTemplate;

		return Resource.Layout._ListItemTemplateInvalid;
	}
}

//Регистрация селектора:
BindingServiceProvider
                .ResourceResolver
                .AddObject("listItemTemplateSelector", new BindingResourceObject(new ListItemTemplateSelector()));

<ListView android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          pkg:Bind="ItemsSource ItemsSource; ItemTemplateSelector $listItemTemplateSelector;" />



Свойтсво ItemsSource, ItemTemplate для iOS поддерживают следующие контролы: UIView, UITabBarController, UISplitViewController, UICollectionView, UITableView.
iOS также поддерживает DataTemplateSelector за это отвечают интерфейсы IDataTemplateSelector, ICollectionCellTemplateSelector и ITableCellTemplateSelector.
Ссылки на примеры, где используется списки для Android и iOS.
2) Я не увидел поддержку ValueConverters, она не предусмотрена?

Поддержка есть, за это отвечает интерфейс IBindingValueConverter. Все конвертеры автоматически регистрируются в ресурсах при старте приложения.
Пример Binding с использованием IBindingValueConverter
//MyColorConverter - класс который реализует интерфейс IBindingValueConverter
Color SourceColor, Converter=MyColorConverter
//Эквивалентный синтаксис
Color $MyColorConverter(SourceColor)



Спасибо за совет про видео, для начала начну писать базовую документацию, а дальше может и для видео время найдется :)

MugenMvvmToolkit — кроссплатформенный MVVM фреймворк

Binding не зависит от компонентов. Для работы Binding в одну сторону (OneWay) из источника в компонент, можно использовать любое свойство компонента. Для работы Binding в две стороны (TwoWay) нужно, чтобы компонент умел уведомлять об изменении свойства, например если свойство называется SelectedIndex, то должно быть событие SelectedIndexChanged.
Что будет, если я захочу использовать компоненты DevExpress или иные? Только допиливать самому?

Если нужного вам свойства или события нет, вы всегда можете использовать присоединяемые свойства, события и методы для того, чтобы расширить тип.
Пример из статьи
var member = AttachedBindingMember.CreateMember<DataGridView, object>("SelectedItem",
    (info, view) =>
    {
        var row = view.CurrentRow;
        if (row == null)
            return null;
        return row.DataBoundItem;
    }, (info, view, item) =>
    {
        view.ClearSelection();
        if (item == null)
            return;
        for (int i = 0; i < view.Rows.Count; i++)
        {
            if (Equals(view.Rows[i].DataBoundItem, item))
            {
                var row = view.Rows[i];
                row.Selected = true;
            }
        }
    }, "CurrentCellChanged"); //CurrentCellChanged - событие в DataGridView, которое отвечает за изменение свойства.
//Регистрация свойства
BindingServiceProvider.MemberProvider.Register(member);


В данном пример, мы сами реализуем свойство SelectedItem для DataGridView. Это очень мощный подход, который позволяет вам добавить желаемое поведение в любой компонент.

MugenMvvmToolkit — кроссплатформенный MVVM фреймворк

1. Насколько фреймворк готов к продакшену? Есть ли выпущенные приложения?

Проект полностью готов к продакшену. В нашей фирме мы активно используем фреймворк для основных проектов. Проекты написаны на WPF, Silverlight и WinForms — это enterprise приложения, они имеет достаточно сложную бизнес логику и состоят из нескольких десятков форм.
Также, сейчас я пишу проект для мобильных платформ, проект находится в стадии разработки.
2. С утечками памяти проблем нет? Насколько я вижу, все View будут создаваться фреймворком, «ручной» доступ к ним будет затруднён. Есть ли уверенность, что View будут вовремя разрушены?

Утечек памяти нет, я много времени провел с профайлером, чтобы этого не допустить. Кроме того, архитектура проекта позволяет самим контролировать процесс создания и освобождения View, за это отвечает интерфейс IViewManager.
В примерах есть проект Binding, там есть счетчик освободившихся ресурсов, чтобы показать, что никаких утечек памяти нет.
3. Убедите меня, что фреймворк будет развиваться и через условный год будет в актуальном состоянии :) Кто-то кроме вас участвует в разработке?

Я пишу этот проект с 2013 года, и у меня нет планов завершать проект. Проект пишу один, т.к. проект нигде особо не «рекламировался» и комьюнити еще не сложилось. Я всегда буду рад помощи, т.к проект open-source, вы всегда можете предложить свою идею или помощь. Если у вас возникнет проблема, вы всегда можете написать мне, и я буду рад помочь в решении вашей проблемы.

В ближайших планах, написать основную часть документации по проекту.

MugenMvvmToolkit — кроссплатформенный MVVM фреймворк

Слишком разные подходы, фундаментально проекты сильно различаются, поэтому было бы сложно реализовать все возможности на базе MvvmCross без полного переписывания.

MugenMvvmToolkit — кроссплатформенный MVVM фреймворк

Есть несколько проектов: Profile259, Profile104, Net 4.0.

MugenMvvmToolkit — кроссплатформенный MVVM фреймворк

Не устраивает тем, что не хватает проработки для каждой платформы. Да, там есть базовый функционал, но взять к примеры Binding, нет ни одного фреймворков, который поддерживает Relative Binding, для всех плафтформ. Или, например работа с Fragment для Android, там есть проблема с сохранением состояния ViewModel, MvvmCross ее до сих пор не решил, вот тема на stackoverflow.
Например, в MVVM Light для показа окна я должен использовать Messenger, вот пример со stackoverflow:
Пример
public void ShowView2CommandExecute()
{
     Messenger.Default.Send(new NotificationMessage("ShowView2"));
}

public partial class View1 : UserControl
{
    public View1()
    {
        InitializeComponent();
        Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);
    }

    private void NotificationMessageReceived(NotificationMessage msg)
    {
        if (msg.Notification == "ShowView2")
        {
            var view2 = new view2();
            view2.Show();
        }
    }
}

Для меня такой способ навигации выглядит некрасиво потому что, я должен на каждой платформе в каждом классе View писать такой код, при этом чтобы узнать, когда окно закроется я опять должен писать код во View, чтобы уведомить ViewModel. Кроме, того я не могу сам создать ViewModel с нужными параметрами потому, что окно само создает ViewModel во время показа с помощью ViewModelLocator.
В случае MugenMvvmToolkit вы сами создаете ViewModel, и для отображения не нужно писать никакой дополнительный код в классе View.

MugenMvvmToolkit — кроссплатформенный MVVM фреймворк

Вы правы, студия не сможет его проверить.
Плагин уже есть, но он для версии 2.1 и не поддерживает Binding, в новой версии плагина, я постараюсь добавить поддержку синтаксиса.

Parallel или в один поток? Внезапные результаты

Ваша проблема не в потоках, а в алгоритме поиска существующих комбинаций. Попробуйте использовать HashSet, вот пример, того как можно ускорить ваш алгоритм в сотни раз:
var result = new HashSet<CardTuple>();
for (int i = 0; i < cards.Count; i++)
    for (int j = 0; j < cards.Count; j++)
        result.Add(new CardTuple(cards[i], cards[j]));

public struct CardTuple : IEquatable<CardTuple>
{
    public bool Equals(CardTuple other)
    {
        return Equals(Card1, other.Card1) && Equals(Card2, other.Card2);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        return obj is CardTuple && Equals((CardTuple)obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ((Card1 != null ? Card1.GetHashCode() : 0) * 397) ^ (Card2 != null ? Card2.GetHashCode() : 0);
        }
    }

    public readonly Card Card1;
    public readonly Card Card2;

    public CardTuple(Card card1, Card card2)
    {
        Card1 = card1;
        Card2 = card2;
    }
}

Использование GPGPU для сжатия данных (Часть I)

Интересно:)
Вначале я планировал сделать и декодирование, но с ним возникли сложности, а так как времени у меня было не много, пришлось его пока отложить, но кое-какие мысли есть!
Однако в сравнении участвовала самая быстрая на данный момент реализация на C++ — FastHuffman.

Не поделитесь?
Прирост где-то около 15-20 процентов, но реализация неоптимальна.

Я не претендую на самую быструю реализацию.

Использование GPGPU для сжатия данных (Часть I)

Насколько я понял, CUDA.NET — это оболочка для CUDA API

Да и CLOO и CUDA.NET это обертки над API.
при этом функцию обработки данных на видеокарте все равно нужно писать на неуправляемом языке, верно?

Исключительно на неуправляемом языке, мы пишем ядро(kernel) для видеокарты, а вызываем мы его из .Net, при этом как ядро будет компилироваться и работать зависит только от вашего драйвера, по сути, это же ядро мы можем вызвать из C/C++, Matlab, и т.д.(все что может работать с OpenCl и CUDA).
Было бы интересно посмотреть сравнение времени работы алгоритма на c для параллельной работы на CPU и вашей реализации на CUDA.NET.

Мне тоже было интересно, но времени писать пока нет.

Использование GPGPU для сжатия данных (Часть I)

Возможно, я выложу код на гитхабе, если выложу, в следующей статье дам ссылку.

Использование GPGPU для сжатия данных (Часть I)

Да, я думаю, жесткий диск тормозит OpenCl и CUDA. Я специально тестировал сначала с записью в файл, а потом без записи. Например, если сравнить результаты:
CPU(Async) без записи 00:01:16.5318999 с записью 01:30.8914603, разница в 14 секунд.
OpenCL без записи 00:00:29.4916041 с записью 00:01:09.3714452, разница в 39 секунд.
Для CUDA аналогично.
Можно увидеть, что для OpenCl и CUDA происходит большой скачек по времени, это связанно с тем, что файл подается порциями и после обработки на видеокарте, файл сначала записывается на диск, а потом запускается следующий кусочек на обработку. Я хотел сделать буффер для обработки и асинхронно записывать в файл, но времени на это не хватило.

Использование GPGPU для сжатия данных (Часть I)

1. OpenCL выполнялся на карте AMD

В следующей статье я выложу программу, и вы сами сможете протестировать. Так получилось что у всех моих знакомых видеокарты Nvidia. Правда до этого у меня была AMD 4850, но она не поддерживала расширение(OpenCl) cl_khr_byte_addressable_store, поэтому я не мог работать на ней с байтами.
2. Файл выходил за пределы памяти, допустим при памяти в 1гб на видеокарте, он занимал 2,2 гб. Соответствующие тесты провести можно было бы для CPU также.

На видеокарту файл подается частями, и теоретически он может быть любого размера.

Использование GPGPU для сжатия данных (Часть I)

Все тоже самое, как и в C/C++, только «хостом» является .Net приложение. Хорошо, в ближайшее время постараюсь написать о .Net и работе с CUDA и OpenCl.
Я использовал библиотеку CLOO для OpenCl, и CUDA.NET для CUDA.

Использование GPGPU для сжатия данных (Часть I)

Вы правы, я уже думал об этом, можно лишь отметить, что Cuda и OpenCl также работают из NET. Ну, если взять лучший вариант для CPU, то время у GPGPU все равно лучше. Также я заметил, что GPGPU работает гораздо быстрее, чем происходит запись в файл, процесс записи в файл одна из долгих операций.

Использование GPGPU для сжатия данных (Часть I)

Да во второй части я размещу exe-файл, для запуска нужен будет только .Net 4.0. Подводных камней быть не должно, вам только нужно будет установить драйвера с поддержкой OpenCl.

Использование GPGPU для сжатия данных (Часть I)

Думаю, что какую-то часть операций можно вынести на GPGPU, но на текущий момент написать архиватор с полной поддержкой GPGPU, не возможно в силу особенностей этих технологий. Наверное в будущем это и будет возможно.

Информация

В рейтинге
6,081-й
Откуда
Красноярск, Красноярский край, Россия
Зарегистрирован
Активность