Пусть есть классы для выполнения комманд (для работы с БД синхронными функциями), + есть декораторы для коман, что бы их можно было вкладывать друг в другна, выпуолнять установочные действия и т.п.
Если команда получает данные из БД, то они предварительно сохраняются во внутреннем сосотянии команды.
Как добавить поддержку ассинхронности, что бы использовать ассинхронные функции для работы с БД внутри комманд?
public class IMyCommand
{
public void Execute();
}
public class MyCommand : IMyCommand
{
public void Execute()
{
//...
}
}
public class MyCommand2 : MyCommand
{
public void Execute()
{
//...
}
public MyCommand2(param1, param2, ...)
{
}
public List<...> Result {get; private set;}
}
public class MyCommand3 : MyCommand
{
public void Execute()
{
//...
}
public MyCommand2(param1, param2, ...)
{
}
public SomeType Result {get; private set;}
}
Хочется:
public async void (или Task<SomeType>) f()
{
MyCommand cmd = CreateComplexCommand();
await cmd.ExecuteAsync();
SomeType result = cmd.result;
}
Здравствуйте, nikda, Вы писали:
N>Пусть есть классы для выполнения комманд (для работы с БД синхронными функциями), + есть декораторы для коман, что бы их можно было вкладывать друг в другна, выпуолнять установочные действия и т.п.
N>Если команда получает данные из БД, то они предварительно сохраняются во внутреннем сосотянии команды.
N>Как добавить поддержку ассинхронности, что бы использовать ассинхронные функции для работы с БД внутри комманд?
Добавить абстракций: команды, диспетчеры, обработчики.
Команды — это просто хранилище входных параметров. Диспетчер подыскивает командам нужный обработчик, вот диспетчера можно декорировать и тем самым добавлять данных в объект команды. Обработчики выполняют команды и вот они уже могут быть асинхронными.
interface ICommand
{
// Общие свойства для примера
// Момент создания команды
DateTime Issued { get; }
// Токен для отмены обработки
CancellationToken CancellationToken { get; set; }
}
interface ICommandDispatcher
{
// Вызов вполне может быть и синхронным без лишнего оверхеда
Task ExecuteAsync(ICommand command)
}
interface IAsyncCommandHandler
{
// Диспетчер может вызывать этот метод в процессе поиска обработчика
bool CanHandle(ICommand command);
Task ExecuteAsync(ICommand command);
}
interface ICommandHandler
{
// Диспетчер может вызывать этот метод в процессе поиска обработчика
bool CanHandle(ICommand command);
void Execute(ICommand command);
}
Подобным образом устроено приложение-читалка этого форума:
https://github.com/vborovikov/rsdn