Search
Write a publication
Pull to refresh
16
0
Александр @shurman

User

Send message
Хочется сказать отдельное спасибо за статью от команды DevExtreme. Такой фидбек о реальном использовании наших продуктов крайне ценен. Многие упомянутые проблемы мы сами видим, разделяем и планомерно устраняем. Совсем недавно мы добавили возможность использовать виртуальный скроллинг с ленивой загрузкой данных с сервера в нативный DevExtreme React Grid.

Также теперь мы даем из коробки React обертку для DevExtreme JavaScript DataGrid. В некоторых сценариях, трудности с управлением внутренним состоянием компонента действительно есть, работаем над этим :)
Пытались заюзать его в нашем проекте, под WP7 не работает совсем.
Как я уже сказал выше — выражение верно синтаксически и скомпилируется если это декларация поля класса, а не локальной переменной.
Т.е. Вы меня пытались убедить что мой пример абсолютно нерабочий, не смотря на то, что этот код безотказно работает уже долгое время, а мои доводы что «it depends» были названы невежеством и попыткой оправдать быдлокод. А теперь на попытку привести хоть какое-то более общее рабочее решение, Вы говорите что его не существует.
Ну и раз уж пошла такая пьянка, давайте улучшим статью вместе и напишем правильную асинхронную стратегию, предлагаю начать, например, с такого варианта:

    public class AsyncStrategy {
        public void DoWork(Action work) {
            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += (s, e) => { work(); };
            worker.RunWorkerCompleted += worker_RunWorkerCompleted;
            worker.RunWorkerAsync();
        }
        private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
            if(e.Error != null) {
                //handle error here
            }
            BackgroundWorker worker = (BackgroundWorker)sender;
            worker.RunWorkerCompleted -= worker_RunWorkerCompleted;
        }
    }


Использование:

            MyWorker worker = new MyWorker();
            AsyncStrategy asyncStrategy = new AsyncStrategy();
            worker.SetDoWorkStrategy(asyncStrategy.DoWork);
Для тех, кто счел данный топик рекомендацией для реализации асинхронности. НИКОГДА не пишите так

(Action work) => { Task.Factory.StartNew(work); }


если не понимаете какими проблемами это может обернуться.

А пример давайте заменим на логирующую стратегию:

(Action work) => {
  Log("Task started");
  work(); 
  Log("Task completed");
}

> this.action = action => action();

Это не объявление поля, а его инициализация, я имел ввиду такой код:

    public class MyClass {
        Action<Action> action = (Action action) => { action(); };
        ...


Он скомпилируется без проблем.

И где здесь вы хотите использовать BackgroundWorker?

   Action<Action> action = (Action action) => { action(); };


И видимо придется третий раз повториться что реализовать асинхронную стратегию каждый может так как ему нравится и как походит для решения его конкретных задач, в соответствии с его принципами и опытом разработки. Представленная статья это не best parctices по реализации асинхронности, а об одном из множества способов изменения поведения класса, который не требует добавления новых сущностей.
Я новичок на хабре, а опыт он приходит с годами. Не думал что каждый байт демонстрируемого здесь кода воспринимается читателями как рекомендация к его использованию в неизменном виде. Мне казалось что каждый его профильтрует и возьмет для себя то что посчитает нужным. В следующий раз буду более осмотрителен при выборе примеров.
> На работу я, может быть, вас и взял бы, но пометил для себя, что на первых порах надо с вами проводить инспекции дизайна.

А сколько бы денег дали? Ну так, ради интереса :)
Все верно, поэтому тесты на асинхронное выполнение не должны полагаться «авось успеет», в этом случае должна быть четкая синхронизация потоков.
> •Верен ли он синтаксически? Скомпилируется ли он?
> Нет, переменная с именем «action» не может быть объявлена в параметрах лямбды/делегата, так как переменная с таким именем уже объявлена.

А если этот объявление поля класса, а не локальной переменной?

> •Как можно улучшить этот код? (Как бы его написали Вы?)
> В C# есть события. Я бы сделал событие с внятным именем.

А могли бы сюда примерчик запостить?
У этой задачи много решений, декоратор — одно из них. Плюс приведенного решения — отсутствие необходимости создавать дополнительные сущности.

Если предположить что стратегий будет только две, я бы все-равно не стал заводить дополнительные классы стратегий, а добавил бы конструктор в MyWorker с bool или enum параметром и в зависимости от него создавал тот или иной делегат внутри класса. И, честно говоря, существующего кода под рукой нет, не исключаю что там так и написано.

При определенных лямбдах проблеммы определенно возникнут, например при таком:

 (Action work) => { throw new Exception(); }
А, значит я Вас не понял, мне показалось Вы говорите о наименовании методов. Спасибо за ссылочки. Об асинхронности можно отдельную статью писать. Я хотел написать о подходе к модификации поведения и простейшей реализации «стратегии». Даже стало интересно сколько человек скопирует код «как есть» к себе в проект, закрыв глаза на ремарку с указанными проблемами.
Мне кажется бессмысленно спорить о качестве абстрактных коней в вакууме. Все понимают что молча глотать все исключения плохо. Все понимают что приложение должно быть стабильным и сообщать о возможных проблемах. Но что мне всегда не нравилось, так это делать работу ради того чтобы сделать работу. Рефакторить код ради того чтобы отрефакторить код. Сообщать о проблемах в висящем таске потому что правильно сообщать о проблемах в висящем таске. Если этот таск присылает мне свежие анекдоты каждый вечер, то мне не нужно с утра лезть в лог сервера, чтобы понять что вчера вечером таск не сработал и не прислал мне свежие анекдоты из-за того что лежал мыльный сервер. Я и так узнаю что таск не сработал, т.к. не получу долгожданный анекдот. И не расстроюсь. Т.к. знаю что этот сервер периодически лежит, и скорее всего завтра анекдот придет снова. И в таком случае я не буду реализовывать уведомления по смс/телефону/радио и т.д., потому что в ДАННОМ КОНКРЕТНОМ случае это не нужно. Затраты не оправдывают результат. Если уж Вы волнуетесь за тех кто скопирует приведенный мной для примера код и завтра из-за этого случайно вылетит баллистическая ракета, то боюсь что она вылетит и без моего топика, возможно неделей позже :)
Да нет, делегаты их конечно не смущают, просто в голове приведенный в самом начале статьи кусок кода очень сложно компилируется :)
Внутри таска у нас ВСЕ исключения обрабатываются, поэтому я могу быть ПОЛНОСТЬЮ уверен что оно не вылетит наружу. А невежественно использовать чужой код не понимая как он работает и какие проблемы в себе несет. В конце топика я специально сделал на этом акцент.
> А почему бы не следовать стандартным паттернам и не сделать Do(), BeginDo(...), EndDo(...)?

Поделитесь о каких паттернах Вы говорите. Когда я пишу код, я люблю чтобы он рассказывал мне и другим что он делает.

> Ваше решение порождает кучу проблем с тем, что вызывающий код не знает, выполняется ли Do синхронно или асинхронно (а теперь на секунду представим, что там, внутри, вылетел exception).

Вообще то я об этом написал в топике

> И не стоит говорить что ваш void-возвращающий метод Pure, ибо такого небывает (или такой метод бесполезен).

Можете не верить, но так и есть

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

Тесты не трогали.

Не совсем понятно что конкретно Вы здесь собираетесь тестировать. В конечном счете wcf сервис это обычный код на сервере, и тестироваться он может также как и любой другой код.
Мне кажется использование workers для AJAX вызовов это неадекватное их использование, т.к. в этом случае асинхронность обеспечивает сам ActiveX объект, который делает HTTP запросы. А смысл появляется только в случае ресурсоемкого JavaScript кода, т.к. весь JavaScript в браузере выполняется в одном потоке. Если бы до появления workers все AJAX запросы были синхронными, то большей частью современных веб-приложений невозможно было бы пользоваться.
1

Information

Rating
Does not participate
Location
Россия
Date of birth
Registered
Activity