Есть некий класс, который принимает в конструктор Action<object>
. Но мне потребовалось передать туда асинхронный метод (то есть Func<object, Task>
). Создал наследника и в конструкторе попытался сделать следующее
public MyClassAsync(Func<object, Task> execute) :
base (async (o)=>await Task.Factory.StartNew(()=>execute?.Invoke(o)))
{ }
Естественно подчеркивает async
и пишет что
asynchronous method anonymous should not return void
А чего мне делать то?
Это не ошибка компилятора. Я насколько понимаю это просто предупреждение о том, что компилятор не знает наверняка как себя вести в такой ситуации. То есть мой код скомпилируется, запустится, но я не знаю наверняка, как он отработает.
UPD:
Я покажу кое что для примера
Вот https://msdn.microsoft.com/ru-ru/library/microsoft.teamfoundation.mvvm.relaycommand(v=vs.110).aspx здесь описание RelayCommand
Вот один из конструкторов
RelayCommand(Action<Object>, Predicate<Object>)
А вот https://msdn.microsoft.com/ru-ru/library/microsoft.teamfoundation.mvvm.asyncrelaycommand(v=vs.110).aspx
AsyncRelayCommand : RelayCommand
и вот соответствующий конструктор
AsyncRelayCommand(Func<Object, Task>, Predicate<Object>, Boolean)
К сожалению я не знаю, где посмотреть на исходники этого. Но что-то мне подсказывает, что если в базовый конструктор передать o => Task.Factory.StartNew(...)
, как предложили в комментариях, то я получу неуправляемую задачу, об окончании которой не смогу узнать.
UPD2
Итак, в конечном счете у меня должны получиться 2 класса
RelayCommand
и AsyncRelayCommand : RelayCommand
Подразумевается использовать их так
public RelayCommand SomeCommand {get;set;}
public RelayCommand SomeAsyncCommand {get;set;}
public Ctor()
{
SomeCommand = new RelayCommand(AnyMethod, Predicate);
SomeAsyncCommand = new AsyncRelayCommand(AnyMethodAsync, Predicate);
}
async Task AnyMethodAsync()
{
await SomeTask;
UIMethod(); // я должен быть уверен, что этот метод выполнится в UI потоке. Конечно, предполагается, что задача сработала посредством взаимодействия пользователя с интерфейсом (по нажатию кнопки или хоткея или еще как)
}
Не получается определить конструктор для AsyncRelayCommand
, так как предполагается использование базового конструктора для RelayCommand
, а он принимает Action
(ну или Action<object>
, но это уже вопрос вариативности), а async метод должен быть типа Func<Task>
(или Func<object,Task>
)
Нет никакой необходимости создавать отдельный класс для запуска асинхронного метода в UI-потоке. Можно использовать для этого обычный RelayCommand если сменить возвращаемое значение на void:
public RelayCommand SomeAsyncCommand { get; } = new RelayCommand(AnyMethodAsync, Predicate);
async void AnyMethodAsync()
{
await SomeTask;
UIMethod();
}
Если возврат Task из метода принципиален - то при вызове метода из команды его можно попросту проигнорировать:
public AsyncRelayCommand(Func<object, Task> execute)
:base (o => execute(o))
{ }
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Подскажите, можно ли запустить в VS 2017 проект MVC3? Вроде, все MVC 3 установлен, но необходимые либы не видит
Когда щелкаешь на часы в Windows 10, открывается панелька часов, календарь и события
Я использую FormattedText класс чтобы рисовать текст наподобие: