Многие методы BufferBlock<T>
действительно принимают CancellationToken
, и я считаю, что это был бы правильный способ сэкономить время. Например:
var cts = new CancellationTokenSource(5000); // cancel in 5s
// Alternatively: cts.CancelAfter(5000);
try
{
var output = await bufferBlock.ReceiveAsync(cts.Token);
}
catch (Exception ex)
{
// check if ex is OperationCanceledException,
// which could be wrapped with AggregateException
}
IMO, единственным способом оценки его эффективности было бы выполнить некоторые профилирующие тесты.
[UPDATE] На основе комментариев, если вы хотите тайм-аут на конвейерную обработку, вы, вероятно, может сделать это, когда вы строите свой ActionBlock
объект и обеспечить его экземпляр ExecutionDataflowBlockOptions
. В этот момент вы можете поставить DataflowBlockOptions.CancellationToken
и использовать его так же, как описано выше. Кроме того, вы можете передать CancellationToken
в LinkTo
в составе DataflowLinkOptions
.
После того, как вы предоставили трубопровод с CancellationToken
, вы можете отслеживать статус ActionBlock.Completion
/TransformBlock.Completion
, который является Task
, так что вы можете await
его и поймать исключение отмены или использовать ContinueWith
с ним (если это то, что вы имеете в виду под каким-то образом, чтобы определить, не закончилась ли «обработка» сообщения).
Отказ от ответственности: Я не пробовал это сам и было бы интересно узнать, работает ли оно так, как ожидалось.
Я не думаю, что есть встроенный тайм-аут. вы можете создать блок с одним, если вы хотите только фильтровать эти элементы, а не просто удалять, чтобы освободить место для других. – i3arnon
Что именно вы подразумеваете под «принуждением тайм-аута»? Вы пытаетесь [отменить отмену операции] (http://blogs.msdn.com/b/pfxteam/archive/2012/10/05/how-do-i-cancel-non-cancelable-async-operations .aspx)? (Я говорю о вашем коде обработки, а не в потоке данных.) – svick