Если это новый проект или вы открыты для серьезного рефакторинга вашего проекта, взгляните на Reactive Extensions. Rx имеет элегантное решение для тайм-аутов в асинхронных вызовах:
var getBytes = Observable.FromAsyncPattern<byte[], int, int, int>(_readStream.BeginRead, _readStream.EndRead);
getBytes(buffer, 0, buffer.Length)
.Timeout(timeout);
Обратите внимание, что приведенный выше код просто предназначен для демонстрации того, как тайм-аут в Rx, и он будет более сложным в реальном проекте.
По производительности я бы не сказал, если вы не профилируете свой конкретный вариант использования. Но я видел разговор, в котором они использовали Rx в сложной платформе, управляемой данными (вероятно, как ваши требования), и они сказали, что их программное обеспечение способно принимать решения менее чем за 30 мс.
С точки зрения кода, я считаю, что использование Rx делает мой код более элегантным и менее многословным.