Я пишу сетевое приложение.
Сообщения отправляются через транспорт как таковой:
Network.SendMessage (new FirstMessage() );
Я могу зарегистрировать обработчик событий, который будет вызываться при появлении этого типа сообщения, например:
Network.RegisterMessageHandler<FirstMessage> (OnFirstMessageReceived);
И событие запускается:
public void OnFirstMessageReceived(EventArgs<FirstMessageEventArgs> e)
{
}
Я пишу пользовательскую процедуру проверки подлинности для своего сетевого приложения, для чего требуется около пяти сообщений.
Без использования параллельной библиотеки задач мне пришлось бы закодировать следующий шаг каждой процедуры в предыдущем обработчике событий, например:
public void OnFirstMessageReceived(EventArgs<FirstMessageEventArgs> e)
{
Network.SendMessage( new SecondMessage() );
}
public void OnSecondMessageReceived(EventArgs<SecondMessageEventArgs> e)
{
Network.SendMessage( new ThirdMessage() );
}
public void OnThirdMessageReceived(EventArgs<ThirdMessageEventArgs> e)
{
Network.SendMessage( new FourthMessage() );
}
public void OnFourthMessageReceived(EventArgs<FourthMessageEventArgs> e)
{
// Authentication is complete
}
Мне не нравится идея прыгать вокруг исходного кода, чтобы закодировать часть этого и часть этого. Это трудно понять и отредактировать.
Я слышал, что параллельная библиотека задач существенно упрощает это решение.
Однако многие из примеров, которые я прочитал, используя параллельную библиотеку задач, были связаны с запуском цепочки активных задач. То, что я подразумеваю под "активным", заключается в том, что каждая задача может запускаться при явном вызове так:
public void Drink() {}
public void Eat() {}
public void Sleep() {}
Task.Factory.StartNew( () => Drink() )
.ContinueWith( () => Eat() )
.ContinueWith( () => Sleep() );
Это противоположно моему асинхронному шаблону, основанному на событиях, в котором каждый метод обработчика событий вызывается только при получении сообщения.
Другими словами, я не могу сделать что-то подобное (но хочу):
Task.Factory.StartNew( () => OnFirstMessageReceived() )
.ContinueWith( () => OnSecondMessageReceived() )
.ContinueWith( () => OnThirdMessageReceived() )
.ContinueWith( () => OnFourthMessageReceived() );
Я читал эту статью, но я не совсем понимаю. Кажется, что мне нужно иметь дело с TaskCompletionSource
. Если бы я хотел сделать задачу из моего async-шаблона, основанного на событиях, например, над блоком кода, как бы он выглядел?