Using .NET TPL DataFlow blocks. Is there any way to timeout the processing of a message?
e.g.
lets say I have a BufferBlock<T>
, is it possible to link that to another block that processes one message at a time (MaxDegreeOfParallellism
1) and force a timeout if the processing runs for too long?
Or is it even possible to do using the BufferBlock only?
I suspect I can use a cancellation token somehow and a delay, but not sure how this would be done. Also, how expensive would such timeout be? would it add much overhead to the message processing time?
Many methods of BufferBlock<T>
do accept CancellationToken
, and I believe that would be the proper way of timing out an operation. E.g.:
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, the only way of evaluating its efficiency would be to run some profiling tests.
[UPDATE] Based upon the comments, if you're looking to time-out the pipeline processing, you can probably do that when you construct your ActionBlock
object and provide it with an instance of ExecutionDataflowBlockOptions
. At that point, you can supply DataflowBlockOptions.CancellationToken
and use it in the same way as described above. Also, you could pass a CancellationToken
into LinkTo
as a part of DataflowLinkOptions
.
Once you've provided the pipeline with a CancellationToken
, you can track the status of ActionBlock.Completion
/TransformBlock.Completion
, which is a Task
, so you can await
it and catch a cancellation exception, or use ContinueWith
with it (if that's what you mean under some way to tell if the "processing" of the message times out).
Disclaimer: I haven't tried this myself and would be interested to know whether it works as expected.