Хочется сказать отдельное спасибо за статью от команды DevExtreme. Такой фидбек о реальном использовании наших продуктов крайне ценен. Многие упомянутые проблемы мы сами видим, разделяем и планомерно устраняем. Совсем недавно мы добавили возможность использовать виртуальный скроллинг с ленивой загрузкой данных с сервера в нативный DevExtreme React Grid.
Также теперь мы даем из коробки React обертку для DevExtreme JavaScript DataGrid. В некоторых сценариях, трудности с управлением внутренним состоянием компонента действительно есть, работаем над этим :)
Т.е. Вы меня пытались убедить что мой пример абсолютно нерабочий, не смотря на то, что этот код безотказно работает уже долгое время, а мои доводы что «it depends» были названы невежеством и попыткой оправдать быдлокод. А теперь на попытку привести хоть какое-то более общее рабочее решение, Вы говорите что его не существует.
Ну и раз уж пошла такая пьянка, давайте улучшим статью вместе и напишем правильную асинхронную стратегию, предлагаю начать, например, с такого варианта:
И видимо придется третий раз повториться что реализовать асинхронную стратегию каждый может так как ему нравится и как походит для решения его конкретных задач, в соответствии с его принципами и опытом разработки. Представленная статья это не best parctices по реализации асинхронности, а об одном из множества способов изменения поведения класса, который не требует добавления новых сущностей.
Я новичок на хабре, а опыт он приходит с годами. Не думал что каждый байт демонстрируемого здесь кода воспринимается читателями как рекомендация к его использованию в неизменном виде. Мне казалось что каждый его профильтрует и возьмет для себя то что посчитает нужным. В следующий раз буду более осмотрителен при выборе примеров.
> •Верен ли он синтаксически? Скомпилируется ли он?
> Нет, переменная с именем «action» не может быть объявлена в параметрах лямбды/делегата, так как переменная с таким именем уже объявлена.
А если этот объявление поля класса, а не локальной переменной?
> •Как можно улучшить этот код? (Как бы его написали Вы?)
> В C# есть события. Я бы сделал событие с внятным именем.
У этой задачи много решений, декоратор — одно из них. Плюс приведенного решения — отсутствие необходимости создавать дополнительные сущности.
Если предположить что стратегий будет только две, я бы все-равно не стал заводить дополнительные классы стратегий, а добавил бы конструктор в MyWorker с bool или enum параметром и в зависимости от него создавал тот или иной делегат внутри класса. И, честно говоря, существующего кода под рукой нет, не исключаю что там так и написано.
При определенных лямбдах проблеммы определенно возникнут, например при таком:
А, значит я Вас не понял, мне показалось Вы говорите о наименовании методов. Спасибо за ссылочки. Об асинхронности можно отдельную статью писать. Я хотел написать о подходе к модификации поведения и простейшей реализации «стратегии». Даже стало интересно сколько человек скопирует код «как есть» к себе в проект, закрыв глаза на ремарку с указанными проблемами.
Мне кажется бессмысленно спорить о качестве абстрактных коней в вакууме. Все понимают что молча глотать все исключения плохо. Все понимают что приложение должно быть стабильным и сообщать о возможных проблемах. Но что мне всегда не нравилось, так это делать работу ради того чтобы сделать работу. Рефакторить код ради того чтобы отрефакторить код. Сообщать о проблемах в висящем таске потому что правильно сообщать о проблемах в висящем таске. Если этот таск присылает мне свежие анекдоты каждый вечер, то мне не нужно с утра лезть в лог сервера, чтобы понять что вчера вечером таск не сработал и не прислал мне свежие анекдоты из-за того что лежал мыльный сервер. Я и так узнаю что таск не сработал, т.к. не получу долгожданный анекдот. И не расстроюсь. Т.к. знаю что этот сервер периодически лежит, и скорее всего завтра анекдот придет снова. И в таком случае я не буду реализовывать уведомления по смс/телефону/радио и т.д., потому что в ДАННОМ КОНКРЕТНОМ случае это не нужно. Затраты не оправдывают результат. Если уж Вы волнуетесь за тех кто скопирует приведенный мной для примера код и завтра из-за этого случайно вылетит баллистическая ракета, то боюсь что она вылетит и без моего топика, возможно неделей позже :)
Внутри таска у нас ВСЕ исключения обрабатываются, поэтому я могу быть ПОЛНОСТЬЮ уверен что оно не вылетит наружу. А невежественно использовать чужой код не понимая как он работает и какие проблемы в себе несет. В конце топика я специально сделал на этом акцент.
> А почему бы не следовать стандартным паттернам и не сделать Do(), BeginDo(...), EndDo(...)?
Поделитесь о каких паттернах Вы говорите. Когда я пишу код, я люблю чтобы он рассказывал мне и другим что он делает.
> Ваше решение порождает кучу проблем с тем, что вызывающий код не знает, выполняется ли Do синхронно или асинхронно (а теперь на секунду представим, что там, внутри, вылетел exception).
Вообще то я об этом написал в топике
> И не стоит говорить что ваш void-возвращающий метод Pure, ибо такого небывает (или такой метод бесполезен).
Можете не верить, но так и есть
>В любом случае вам пришлось модифицировать тесты, как минимум их инициализаторы.
Не совсем понятно что конкретно Вы здесь собираетесь тестировать. В конечном счете wcf сервис это обычный код на сервере, и тестироваться он может также как и любой другой код.
Мне кажется использование workers для AJAX вызовов это неадекватное их использование, т.к. в этом случае асинхронность обеспечивает сам ActiveX объект, который делает HTTP запросы. А смысл появляется только в случае ресурсоемкого JavaScript кода, т.к. весь JavaScript в браузере выполняется в одном потоке. Если бы до появления workers все AJAX запросы были синхронными, то большей частью современных веб-приложений невозможно было бы пользоваться.
Также теперь мы даем из коробки React обертку для DevExtreme JavaScript DataGrid. В некоторых сценариях, трудности с управлением внутренним состоянием компонента действительно есть, работаем над этим :)
Использование:
если не понимаете какими проблемами это может обернуться.
А пример давайте заменим на логирующую стратегию:
Это не объявление поля, а его инициализация, я имел ввиду такой код:
Он скомпилируется без проблем.
И где здесь вы хотите использовать BackgroundWorker?
И видимо придется третий раз повториться что реализовать асинхронную стратегию каждый может так как ему нравится и как походит для решения его конкретных задач, в соответствии с его принципами и опытом разработки. Представленная статья это не best parctices по реализации асинхронности, а об одном из множества способов изменения поведения класса, который не требует добавления новых сущностей.
А сколько бы денег дали? Ну так, ради интереса :)
> Нет, переменная с именем «action» не может быть объявлена в параметрах лямбды/делегата, так как переменная с таким именем уже объявлена.
А если этот объявление поля класса, а не локальной переменной?
> •Как можно улучшить этот код? (Как бы его написали Вы?)
> В C# есть события. Я бы сделал событие с внятным именем.
А могли бы сюда примерчик запостить?
Если предположить что стратегий будет только две, я бы все-равно не стал заводить дополнительные классы стратегий, а добавил бы конструктор в MyWorker с bool или enum параметром и в зависимости от него создавал тот или иной делегат внутри класса. И, честно говоря, существующего кода под рукой нет, не исключаю что там так и написано.
При определенных лямбдах проблеммы определенно возникнут, например при таком:
Поделитесь о каких паттернах Вы говорите. Когда я пишу код, я люблю чтобы он рассказывал мне и другим что он делает.
> Ваше решение порождает кучу проблем с тем, что вызывающий код не знает, выполняется ли Do синхронно или асинхронно (а теперь на секунду представим, что там, внутри, вылетел exception).
Вообще то я об этом написал в топике
> И не стоит говорить что ваш void-возвращающий метод Pure, ибо такого небывает (или такой метод бесполезен).
Можете не верить, но так и есть
>В любом случае вам пришлось модифицировать тесты, как минимум их инициализаторы.
Тесты не трогали.