Цель: Реализация длительных операций.
Результаты: После выполнения работы Вы сможете:
Некоторые из команд не могут выполнить всю работу за один вызов метода Execute без блокирования на длительное время выполнения всех остальных командд из очереди.
Например, если какая-нибудь сетевая игра представлена командой, то пока одна игра не закончится, следующая не начнется. Чтобы эффективнее использовать процессорные
можности, нужно обеспечить возхможность поиграть как можно большему количеству игроков.
Для этого используют режим псевдопараллельной обработки. Когда все время работы разбивают на небольшие отрезки, каждый из которых выполняется
за один вызов метода Execute. Чтобы выполнить всю работу, нужно вызвать метод Execute несколько раз, до тех пор пока работа не будет завершена.
Это позволяет между вызовами Execute одного экземплыра команды вызывать метод Execute других команд.
Так устроен, например, ренедринг страницы в браузере. Только в браузеоре это используется не для рендеренга всех вкладок, а для обработки
реакций пользователя на странице.
В прошлой работе все команды, которые выполнялись в потоке, брались из очереди. Поэтому первая идея - это положить долгоиграющую операцию обратно в очередь.
Но это может привести к состоянию мертвой блокировки потока: если очередь будет полна, то поток, который попытается сделать запись, будет заблокирован до тех пор,
пока в очереди не появится свободное место. Поэтому нельзя в одном и том же потоке читать и писать в очередь неблокируемым образом.
Чтобы избежать мертвой блокировки потока, необходимо ввести понятие Планировщика, который будет отвечать за выбор следующей длительной задачи для выполнения,
а чтение из очереди оставить только для новых операций.
public interface IScheduler
{
bool HasCommand()
ICommand Select();
void Add(ICommand cmd);
}
Необходимо реализовать поток, который способен реализоввывать длительные операции.
Указание.
С другой стороны, если будем всегда читать неблокируемым образом, а в планировщике нет никакой работы, то будем тратить процессорное время без полезной нагрузки.
Необходимо учесть этот момент при реализации очереди.
Для обепечения справедливости стратегии планировщика в слабом смысле использовать стратегию Round Robbin (циклическую) для определения следующего потока на исполнение.
Написать набор тестов.