2014-01-07 2 views
2

Использование блоков данных .NET TPL DataFlow. Есть ли способ отключить обработку сообщения?Тайм-аут обработки сообщений TPL.Dataflow?

например.

позволяет сказать, что у меня есть BufferBlock<T>, можно ли связать это с другим блоком, обрабатывающим одно сообщение за раз (MaxDegreeOfParallellism 1) и заставить таймаут, если обработка длится слишком долго? Или это возможно сделать только с помощью BufferBlock?

Я подозреваю, что могу использовать маркер отмены как-то и задержать, но не уверен, как это будет сделано. Кроме того, насколько дорого будет такой тайм-аут? добавит ли он много накладных расходов на время обработки сообщений?

+0

Я не думаю, что есть встроенный тайм-аут. вы можете создать блок с одним, если вы хотите только фильтровать эти элементы, а не просто удалять, чтобы освободить место для других. – i3arnon

+1

Что именно вы подразумеваете под «принуждением тайм-аута»? Вы пытаетесь [отменить отмену операции] (http://blogs.msdn.com/b/pfxteam/archive/2012/10/05/how-do-i-cancel-non-cancelable-async-operations .aspx)? (Я говорю о вашем коде обработки, а не в потоке данных.) – svick

ответ

2

Многие методы 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 с ним (если это то, что вы имеете в виду под каким-то образом, чтобы определить, не закончилась ли «обработка» сообщения).

Отказ от ответственности: Я не пробовал это сам и было бы интересно узнать, работает ли оно так, как ожидалось.

+2

Спасибо, что выше код, однако, отменит, если время получения, мне нужно каким-то образом сказать, если «обработка» сообщения истекает. но возможно, что это возможно, если я передаю сообщение через свой процессор и переадресую его на другой блок –

+0

@RogerAlsing, я так думаю. Вы могли бы, вероятно, использовать для этого 'token.Register' и/или' CreateLinkedTokenSource'. Возможно, вы можете показать эскиз своего кода обработки. – Noseratio

+0

Код, который должен быть указан по выделенной строке: https://github.com/rogeralsing/Pigeon/blob/master/Pigeon/Actor/Mailbox.cs#L34 Я использую буферный блок как наблюдаемый там, но это никоим образом не является обязательным требованием, я просто хочу вызывать «onNext», как только получаю сообщение из буфера, а если он выполняется больше, чем x, то бросайте –

Смежные вопросы