Ich habe eine BroadcastBlock
mit ActionBlock
verbunden. Wenn ich sequentiell sowohl auf BroadcastBlock
als auch auf ActionBlock
"complete" anrufe, funktioniert es nicht. Während das Aufrufen von "complete" auf BroadCastBlock
allein funktioniert, funktioniert.Linked DataFlow Block Fertigstellung funktioniert nicht
public class ActionTester
{
private readonly ActionBlock<int> _action;
private readonly BroadcastBlock<int> _input;
public ActionTester()
{
_input = new BroadcastBlock<int>(null);
_action = new ActionBlock<int>(i => Process(i));
_input.LinkTo(_action, new DataflowLinkOptions { PropagateCompletion = true });
}
public void Post(int i) => _input.Post(i);
public async Task Process(int i)
{
await Task.Delay(2000);
Console.WriteLine(i);
}
public void Complete()
{
_input.Complete();
_action.Complete(); // When this is removed, program is working as expected
}
public Task Completion => _action.Completion;
}
Der Testcode ist
static void Main(string[] args)
{
var actor = new ActionTester();
actor.Post(5);
actor.Post(7);
actor.Complete();
actor.Completion.Wait();
Console.WriteLine("Finished");
Console.Read();
}
Wenn _action.Complete()
vorhanden (kommentierte Linie), Code bewegt Vergangenheit actor.Completion.wait()
und "Fertig" angezeigt bekommen. Wenn ich _aciton.Complete()
entferne, werden die geposteten Werte richtig angezeigt und dann wird "Beendet" geschrieben.
Wenn Datenflussblöcke verknüpft sind, sollten wir nur "Complete" des Root-Blocks aufrufen? Die Einstellung PropagateCompletion
auf wahr/falsch hat keine Auswirkungen.
Lösung
Gelöst für den Root-Block Abschluss durch das Warten
public void Complete()
{
_input.Complete();
_input.Completion.Wait();
_action.Complete();
}
Wenn "PropogateCompletion" auf false gesetzt ist, sollten wir nicht alle verknüpften Blöcke als abgeschlossen bezeichnen? In meinem Beispiel, selbst wenn ich PropagateCompletion auf false gesetzt habe, funktionierte es nicht, wenn ich einen weiteren Aufruf für den verknüpften Block abgeschlossen habe. – Saravanan
Wenn Sie den zweiten Block ** vor ** abschließen, werden alle Nachrichten von der ersten an die zweite gesendet, die zweite Nachricht verwirft alle. Also, wenn Sie die Fertigstellung nicht weitergeben, müssen Sie es selbst behandeln. – VMAtm