2016-07-09 5 views
1

Ich bin ziemlich neu in dem ganzen Thema und als Training habe ich beschlossen, einen GREP-Klon zu schreiben, mit dem, was ReactiveExtensions und async/await zu bieten haben.Transformerblock nicht an Actionblock

Der folgende Code gibt die im transformblock transformierten Elemente nicht an den resultHandler weiter.

var flowOptions = new DataflowLinkOptions {PropagateCompletion = true}; 

    .... 

    private static Task _searchTermInFilesAsync(Options options, 
               CancellationToken token, 
               ExecutionDataflowBlockOptions executionOptions, 
               ActionBlock<FileSearcherResult> resultHandler, 
               DataflowLinkOptions flowOptions) 
    { 
     var enumerator = new TransformManyBlock<Options, FileData>(o => _enumerateFiles(o).TakeWhile(_ => !token.IsCancellationRequested), executionOptions); 

     var handleFile = new TransformBlock<FileData, FileSearcherResult>(async data => await _handleFile(options, data), executionOptions); 

     enumerator.LinkTo(handleFile, flowOptions); 

     handleFile.LinkTo(resultHandler, flowOptions, result => result != null); 

     enumerator.Post(options); 
     enumerator.Complete(); 

     return resultHandler.Completion; 
    } 

Ich habe ein ähnliches Verfahren fast die gleiche Arbeit, ist der einzige Unterschied, dass es keine transformblock ist (die andere Methode nur dann verwendet wird, um Dateien für die Namepattern aufzählen). Beide Methoden verwenden denselben resultHandler, so dass davon ausgegangen werden kann, dass er korrekt funktioniert.

Warum also bringt der TransformBlock keine Ergebnisse in den resultHandler? Ich habe überprüft, dass keine Null-Ergebnisse erzeugt werden.

EDIT Anscheinend ist der Filter fehlerhaft.

handleFile.LinkTo(resultHandler, flowOptions); //, result => result != null); 

Wenn ich es auskommentieren, funktioniert es. Seltsamerweise gibt es dort auch "Notnull" -Ergebnisse. Es scheint, dass der Filter das Ganze stoppt, sobald es falsch zurückgibt.

+0

Können Sie eine [MCVE]? – svick

+0

Auch dies ist wahrscheinlich unabhängig von Ihrer Frage, aber Ihre Rückkehr ist falsch. 'ContinueWith()' gibt 'Task 'zurück und du ignorierst die innere Aufgabe. Da es keinen Grund geben sollte, explizit auf 'handleFile' zu ​​warten, würde ich nur' return resultHandler.Completion; 'verwenden. – svick

+0

Siedecode für das vollständige Beispiel. – CSharpie

Antwort

1

Seltsamerweise gibt es dort auch "notnull" Ergebnisse.

Das ist nicht seltsam. Jeder Block mit Ausgabe hat einen Ausgang Warteschlange. Die Elemente verlassen diese Warteschlange in der Reihenfolge, in der sie angekommen sind (dies wird auch als FIFO bezeichnet). Dies bedeutet, dass, wenn eine null ankommt und es keinen Block zum Empfang gibt, die Verarbeitung stoppt.

Die einfachste Lösung ist es, einen Block hinzuzufügen, die diese null s akzeptieren, aber mit ihnen nichts zu tun:

handleFile.LinkTo(DataflowBlock.NullTarget<FileSearcherResult>(), result => result == null); 
+0

Das hat den Trick gemacht. Ich vermute, ich habe völlig falsch verstanden, wie die Dinge hier funktionieren. – CSharpie