2013-04-12 10 views
5

Chciałbym wiedzieć, czy można zmienić stan ukończenia bloków danych?Przepływ danych zadania, czy blok danych można zmienić ze stanu zakończenia?

Na przykład oznaczyłem blok danych var block = new BufferBlock<int>(); kompletny z block.Complete(). Blok jest powiązany z innymi blokami danych. Chciałbym wiedzieć, czy mogę ponownie uruchomić block, zmieniając jego stan ukończenia z powrotem na pierwotny stan!

Jeśli nie jest to możliwe, w jaki sposób mogę wykonać wiele przebiegów, w tym zakończenie, bez konieczności a) odłączyć wszystkie bloki, b) ponownie utworzyć wszystkie bloki i c) ponownie połączyć wszystkie bloki?

Wszelkie pomysły, które mogą ułatwić wykonywanie cykli przepływu danych, w tym wykonanie każdego bloku w dół łańcucha bez konieczności ponownego tworzenia całego frameworka?

Dzięki

+1

Dlaczego potrzebujesz nawet osobnych serii? Ponadto, dlaczego nie chcesz odtworzyć sieci przepływu danych? Wątpię, że wpłynie to na wydajność (chyba że robisz to wiele razy na sekundę), a także nie powinno sprawić, by twój kod był bardziej skomplikowany. – svick

+0

Oddzielne przebiegi są częścią wymagania. Ponowne utworzenie całej sieci całkowicie zniszczyłoby wydajność uzyskaną dzięki wyborowi przepływu danych tpl. Głównym bólem głowy jest odłączanie i ponowne łączenie, a nie ponowne odtwarzanie każdego bloku przepływu danych. Jeśli zmiana stanu zakończenia nie jest możliwa, w jaki sposób mógłbym w inny sposób zasygnalizować zakończenie bez wpływu na stan zakończenia każdego bloku przepływu danych? Nie mogę po prostu wysłać flagi atomowej, ponieważ typy obiektów w dół łańcucha nie są identyczne (w tym przypadku są zaangażowane transformatory). –

Odpowiedz

3

Nie, nie można "zakończyć" ukończonego bloku przepływu danych. Myślę, że powinieneś dodać flagę do każdej wiadomości, która mówi, czy to ostatnia wiadomość w biegu. Aby uprościć pracę z nim, można utworzyć zestaw metod pomocniczych, takich jak:

public static TransformBlock<Tuple<TInput, bool>, Tuple<TOutput, bool>> 
    CreateEnhancedTransformBlock<TInput, TOutput>(Func<TInput, TOutput> transform) 
{ 
    return new TransformBlock<Tuple<TInput, bool>, Tuple<TOutput, bool>>(
     tuple => Tuple.Create(transform(tuple.Item1), tuple.Item2)); 
} 

ten sposób można wprowadzić transform delegata, który zajmuje tylko z TInput i TOuput a flaga jest przenoszone wraz z każdej wiadomości.

+0

Interesujący pomysł, czy chcesz opisać obciążenie obliczeniowe podczas wykonywania, przechodząc tę ​​trasę? Do tej pory widzę tylko dodatkową kontrolę "flagi ukończenia" bloku odbiornika dla każdej przychodzącej wiadomości. Coś jeszcze pomijam? Czy zamiast wysyłki bool zamiast droższych statków byłoby znacznie droższe? W ten sposób mogłem komunikować inne państwa niż tylko zakończenie. –

+1

@Freddy Może pojawić się niewielki narzut, ponieważ istnieją dwa wywołania delegatów zamiast jednego, ale to powinno być naprawdę pomijalne. I myślę, że zamiana 'bool' na enum nie powinna wpływać na wydajność. – svick

+0

zdecydowanie dobry pomysł, aby rozwiązać ten problem, ale w końcu poszedłem z twoją pierwszą radą: Rozumiem funkcję dokładnego ukończenia bloków danych i odtworzyć cały rurociąg. Dostarczam wywołania zwrotne do bloku danych typu "upstream" zawierającego moduły, a po zakończeniu każdego bloku danych go ponownie tworzy i przekazuje za pośrednictwem wywołania zwrotnego w dół, gdzie dwa bloki są ponownie połączone. –

Powiązane problemy