У меня есть следующий код, определенный в viewmodel. Я думаю, что SaveAsync типа Func<Task>
преобразуется в Action, так как RelayCommand принимает Action, а не Func<Task>
, но я не понимаю последствий этого.
1) Нужно ли заменить RelayCommand асинхронной версией (RelayCommandAsync)? 2) Что именно делает текущий код в отношении асинхронности? 3) Что делать, если что-нибудь может/нужно изменить, чтобы улучшить/исправить?
private ICommand _saveCommand;
public ICommand SaveCommand
{
get { return _saveCommand ?? (_saveCommand = new RelayCommand(async () => await SaveAsync(), CanSave)); }
}
public bool CanSave()
{
return !IsBusy;
}
private async Task SaveAsync()
{
IsBusy = true;
try
{
await _service.SaveAsync(SomeProperty);
}
catch ( ServiceException ex )
{
Message = "Oops. " + ex.ToString();
}
finally
{
IsBusy = false;
}
}
Спасибо!
РЕДАКТИРОВАТЬ: После некоторых экспериментов выяснилось, что сам метод async работает. И не имеет значения, включен ли асинхронный/ожидаемый в лямбда, и не был ли метод определен как async Task
или async void
.
Однако, что не работает правильно, это предикатная функция canExecute
, которая автоматически включает/отключает привязку элемента управления к команде. Случается, что кнопка корректно отключена, когда выполняется метод async, но после этого она не включена. Мне нужно щелкнуть где-нибудь в окне один раз, а затем снова включить.
Итак, кажется, что для полной функциональности требуется асинхронная версия RelayCommand, т.е. canExecute
может правильно выполнить свою работу.