|
1 / 1 / 1
Регистрация: 07.03.2018
Сообщений: 98
|
||||||
.NET 10 Как правильно реагировать на отмену операции пользователем?23.02.2026, 20:39. Показов 721. Ответов 11
У меня есть метод-обёртка для асинхронных операций, который управляет состоянием (Begin/EndOperation) и обрабатывает исключения. Пользователь нажимает кнопку – запускается
ExecuteAsync. Если он нажимает кнопку снова, первый вызов прерывается исключением OperationCanceledException, а второй стартует.Поскольку отмена ожидаема и инициирована самим пользователем, я не хочу показывать ему сообщение об ошибке. Но оставлять блок catch пустым кажется неправильным. Сейчас я возвращаю Errors.Common.OperationCancelled, но тогда в вызывающем коде приходится каждый раз проверять, не является ли ошибка отменой, чтобы скрыть уведомление. Возможно, есть более элегантное решение?Упрощённая версия метода:
OperationCanceledException?P.S. Также интересуют общие рекомендации по оформлению catch (Exception ex) в подобных методах-обёртках: что логировать, возвращать ли пользователю ex.Message или лучше обобщённое сообщение, стоит ли перехватывать Exception вообще?
0
|
||||||
| 23.02.2026, 20:39 | |
|
Ответы с готовыми решениями:
11
Сделать так что бы на событие mouseEnter реагировал только canvas, но не реагировали находящиеся в нем компонеты Как отменить запуск анимации в Style.ItemTemplate Как простым способом отменить изменения в ячейках DataGrid? |
|
Модератор
|
||
| 23.02.2026, 21:44 | ||
|
В концепции MVVM: 1) Есть Model в которой инкапсулирована вся Бизнес (Доменная) Логика. 2) Есть View в которой вся Логика представления. Здесь должны быть описаны все правила и требования к пользовательскому интерфейсу. В данном случае: 1. Пользователь нажимает кнопку и ожидает такого результата.3) К уже имеющимся Model и View, с уже сформированными требованиями и правилами для потребителя Model и поставщика данных для View, создаётся ViewModel функция которой только одна: отразить Model в удобном для View виде. Поэтому не получив от вас задания, что вы (вернее пользователь вашего приложения) хотите увидеть в View при определённых действия, невозможно сказать как это лучше реализовать. В данном случае, возможные решения, которые на вскидку пришли мне в голову: - Окно предупреждения перед перезапуском выполнения; - Окно уведомление о перезапуске; - Сброс прогресс бара; - Логирование ошибки.
1
|
||
|
|
||||
| 24.02.2026, 12:04 | ||||
|
Stormhead, многое будет зависеть от того, как и какие исключения обрабатываются в самих 'operation'. Если в какой-то из переданных operation нет обработки исключений, то данный метод-обёртка тоже ничего не обнаружит и не вернет.
Если же в каком-то месте кода исключение ожидается и оно прогнозируемое, то лучше обойти его логическим путем, а не try/catch-ем.
0
|
||||
|
|
|
| 24.02.2026, 12:36 | |
|
Stormhead, Вообще-то всё управляется через VM, написанными в этом слое командами. В пакете CommunityToolkit есть класс команды - AsyncRelayCommand(). И именно этими командами можно всё настроить - Ожидание, Отмену и т.д.
0
|
|
|
Модератор
|
||
| 24.02.2026, 18:23 | ||
|
По вашему коду, больше похоже на второй случай. И ExecuteAsync - это метод ViewModel, в таком случае.Но зачем он тогда возвращает Таск? Для команд нужен void метод. В общем случае (для Форм, WPF, UWP и др. GUI платформ), иерархия async методов строится так: - на нижних уровнях Task методы. В них обрабатываются только исключения, которые нужны на их уровне. Например, при ошибке доступа к порту надо повторить его 10 раз. Все остальные исключения обрабатываться не должны или должны перевыкидываться. Например, после 10-го исключения доступа к порту, выкидвается исключение "10 ошибок соединения" Task методы вкладываются друг в друга через await и при исключении на любом уровне оно автоматически прокидывается на самый верхний уровень. - на верхнем уровне находится уже void метод, который вызывается из синхронного потока (главного потока приложения). В нём может происходить обработка исключения, чтобы при ожидаемых исключениях, приложение не падало. Не обрабатываются только исключения критические для приложения, при выкидывании которых, приложение обязано экстренно прекратить работу. Обработка исключений может быть индивидуальной в каждом void методе. Но при большом количестве таких методов и более менее стандартизированной обработке, можно их делать централизовано, в каком-то общем классе или методе. Так же исключения централизовано можно обрабатывать в Application.DispatcherUnhandledException . Сюда попадают все исключения из пула Диспетчера. Верхние void методы в WPF выполняются в пуле Диспетчера, поэтому если их необрабатывать они все попадут в это событие. При какой-то похожести обработки в DispatcherUnhandledException и централизованной в void методе, между ними есть концептуальная разница. void Метод - это уровень ViewModel. DispatcherUnhandledException - это уровень приложения, который даже не входит не в один слоёв паттерна MVVM. Он лежит на всеми слоями и "знает обо всём".
1
|
||
|
|
|
| 24.02.2026, 19:01 | |
|
Тут, на самом деле, не совсем ясно в каком ключе автор задал вопрос. Привязки именно к MVVM-паттерну в вопросе не прослеживается.
Приведенный ТС-ом код точно не для размещения в VM: vm лишь, по какой-то команде, вызовет его из модели (не важно какой). А вот уже модель, на основании возвращенного результата отработавшего метода, уже создаст событие, на которое должна реагировать VM, со всеми своими "примочками", типа сообщений в окне или мессадж-боксах. Глобальный перехват "необслуживаемых" исключений можно делать в App, так же, отдельным классом, который там инициализируется. Но такой подход предполагает наличие таких исключений из "ни от куда", которые явно нельзя предусмотреть заранее. И не является хорошей практикой..
2
|
|
|
1 / 1 / 1
Регистрация: 07.03.2018
Сообщений: 98
|
|||||||||
| 26.02.2026, 17:45 [ТС] | |||||||||
BaseViewModel под свойство IsBusy для Loader'а в View. Сейчас понимаю, что не каждому VM необходим данный функционал, и исходя из сообщения wizard41, вовсе не должен присутствовать в VM.Result.
Есть над чем подумать, но пока что откажусь от этой идеи и вернусь к ней в конкретный момент нужды. Спасибо за все сообщения. Если вам есть что ещё сказать - всегда готов выслушать.
0
|
|||||||||
|
Модератор
|
|||||||
| 26.02.2026, 20:32 | |||||||
|
Что такое для неё IsBusy?Например, есть некое устройство, которое может работать только синхронно и выполнять одномоментно одну команду. IsBusy отражает состояние этого устройства когда оно уже приняло какую-то команду и другую ему уже передавать нельзя.А может быть такое, что устройство выполнять может несколько команд одновременно, но некоторые из них она повторно принять не может пока не завершит выполнение предыдущей такой же? Да, может. И в этом случае IsBusy это уже состояние не устройства в целом, а только состояние по отношению к определённому методу.А как часто мы должны проверять IsBusy? Логично, если устройство нам сообщает об изменении своего состояния и по нему перепроверяем IsBusy.Вот обобщением всего этого и является команда - интерфейс ICommand. ICommand.Execute - запускает метод (команду устройства) Модели. ICommand.CanExecute - проверят IsBusy Модели и определённого Метода.ICommand.CanExecuteChanged - служит для извещения о необходимости перепроверки ICommand.CanExecute и, следовательно, перепроверки IsBusy Модели.Имеет ли смысл вешать IsBusy на ViewModel в целом?В общем случае нет, поскольку IsBusy на модели (устройстве) хоть и частый сценарий, но не относится к большей части. Поэтому ICommand.CanExecute хватает для почти всех сценариев.Подходим к следующей итерации усложнения - Асинхронным командам. Асинхронная команда - это всего лишь Task обертка:
execute. Нужна она там или нет - "личное дело" метода.На практике, это очень зависит от конкретного задания. В целом принято различать ошибки и критические исключения. Ошибки - это исключения при которых можно продолжить работу приложения. Например, повторить запрос. Или сообщить пользователю, что неверный адрес. Критические исключения - их тоже обрабатываю, но обычно это просто вывод сообщения пользователю и/или запись лога перед прекращением работы приложения. Можно ли сделать типичным обработку приложения. В общем случае - нет. Но в контексте какой-то предметной области, какой-то специализации разработки - можно. Например, можно прокидывать все необработанные исключения в поток диспетчера. А на Application.DispatcherUnhandledException повесить запись лога, вывод окошка с сообщением и Shutdown приложения. Так же может быть в каких-то случаях и какая-то типизированная обработка всех исключений в конкретном приложении. Но этот функционал точно не относится к обобщённой ViewModel.
3
|
|||||||
|
|
||
| 27.02.2026, 12:50 | ||
|
0
|
||
|
1 / 1 / 1
Регистрация: 07.03.2018
Сообщений: 98
|
||
| 27.02.2026, 19:13 [ТС] | ||
|
0
|
||
|
Модератор
|
||
| 27.02.2026, 19:25 | ||
|
Один из вариантов, это полупрозрачный фон в контроле с прогрессбаром в AdornerLayer и перекрывающий весь GUI. Его видимость привязана к IsBusy в VM.
0
|
||
| 27.02.2026, 19:25 | |
|
Помогаю со студенческими работами здесь
12
Отмена сворачивания окна WebBrowser и MVVM отловить и отменить событие клика Отмена действий горячих клавиш
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git
main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели
8ATzM_2aurI
|
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2.
Задача: запретить редактирование документа, если он открыт у другого пользователя.
/ / . . .
|
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои.
А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
|
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20%
kYBz3eJf3jQ
|
|
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
|
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
|
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора
Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2.
Задача: уведомлять пользователя, если. . .
|
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2.
Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
|