2014-09-02 108 views
3

如果這是一個簡單的問題,那麼我對TPL數據流很熟悉,所以請原諒我。如何在TPL Dataflow中分支邏輯?

我有一個輸入緩衝區塊,需要一個基類。我如何從那裏分支到基於派生類型的塊?例如:

var inputBlock = new BufferBlock<EventBase>(); 
//if EventBase is Meeting then go to block X 
//if EventBase is Appointment the go to block Y 

謝謝!

+1

你不知道。這就是多態的完整點。您應該讓每個派生類型以基類型成員的方式區分其行爲。 – Servy 2014-09-02 14:48:28

+0

那麼你說的沒有辦法做到這一點?我可以在TPL數據流之外的一個循環中完成它,並且只要(EventBase是Meeting){},我要問的是數據流塊中的數據流是如何完成的?我需要一個自定義塊嗎? – jmichas 2014-09-02 15:16:38

+1

我不告訴你這是不可能的,我告訴你這是個壞主意。這表示設計不好。你*不應該*這樣做。相反,您應該通過使用多態性來設計塊以支持任何類型的「EventBase」。 – Servy 2014-09-02 15:19:01

回答

5

您可以發送謂詞到LinkTo方法來區分這些項目。然而,你將需要從EventBase到垂頭喪氣每塊內使用邏輯與特定種類:

var inputBlock = new BufferBlock<EventBase>(); 
var meetingBlock = new ActionBlock<EventBase>(
    eventBase => 
    { 
     var meeting = eventBase as Meeting; 
     //... 
    }); 
var appointmentBlock = new ActionBlock<EventBase>(
    eventBase => 
    { 
     var appointment = eventBase as Appointment; 
     //... 
    }); 

inputBlock.LinkTo(meetingBlock, eventBase => eventBase is Meeting); 
inputBlock.LinkTo(appointmentBlock, eventBase => eventBase is Appointment); 

但作爲Servy指出你應該避免和設計類型來支持多態。

+0

謝謝,這看起來像什麼林後。我明白你們對這是不好的設計說什麼,不幸的是,在上游供應商的憐憫和他們的XML塊設計有點差,以減輕我的反序列化問題的一個xml數組其中會議和約會節點是最簡單的用基類反序列化並按照這種方式處理邏輯。有很好的可能是一個更好的設計,但在這一點上我很遠,不想回到反序列化代碼。 – jmichas 2014-09-02 17:07:19

1

如果你想有一個簡單的解決方案,並且不介意使用時TPL數據流建立一個輔助庫,有DataflowEx它提供了一個LinkSubTypeTo()方法

Dataflow<TIn, TOut> flow1; 
Dataflow<TOutSubType1> flow2; 
Dataflow<TOutSubType2> flow3; 

flow1.LinkSubTypeTo(flow2); 
flow1.LinkSubTypeTo(flow3); 

請檢查圖書館文件的advanced linking部分。它在內部使用了@ I3arnon引入的相同機制。

聲明:我是DataflowEx的作者。