Ich versuche, ein einfaches Programm zum besseren Verständnis TPL Dataflow zu machen. Ich versuche, eine lange laufende Aufgabe zu erstellen, die einen Datenflussblock neu startet, wenn er abgeschlossen ist.ActionBlock wird nie bei Fehlerzustand abgeschlossen
Meine aktuelle RestartActionBlock
Task ist in der Lage, auf die Fertigstellung der ActionBlock
zu warten, wenn ich auf dem Block explizit durch Eingabe von "-1" den Aufruf abschließe. Aber wenn ich versuche, eine Ausnahme auszulösen, um den Block zu blockieren oder die Blöcke Fault() - Interface-Methode aufzurufen, wird die Completion-Task ActionBlock
niemals abgeschlossen. In dieser Situation wird der await singleTestFlow.Completion;
Anruf nie fortgesetzt.
Nach dem Auslösen der Ausnahme oder dem Aufrufen der Fault() -Methode kann ich sicher sein, dass der Block im fehlerhaften Zustand ist, indem versucht wird, eine andere Eingabe in das Programm einzugeben und den Code zu prüfen, um festzustellen, ob der Block fehlerhaft ist :
Wenn der Block in dem Fehlerzustand ist, warum zurückgekommen die await singleTestFlow.Completion;
nie?
class Program
{
private static ActionBlock<string> singleTestFlow;
static void Main(string[] args)
{
//start thread that should restart a completed action block
Task.Run(RestartActionBlock);
Console.WriteLine("Enter -0 to exit, -1 to complete flow, -0- to throw an exception, Anything else otherwise");
var input = Console.ReadLine();
//allow user to input text until "-0" is entered
while (!input.Equals("-0"))
{
if (input.Equals("-1"))
{
singleTestFlow.Complete();
}
singleTestFlow.Post(input);
input = Console.ReadLine();
}
async Task RestartActionBlock()
{
var iterations = 0;
while (true)
{
singleTestFlow = new ActionBlock<string>(s =>
{
if (s.Equals("-0-"))
{
//throw new Exception("Something went wrong in here");
((IDataflowBlock)singleTestFlow).Fault(new Exception("Something went wrong in here"));
}
Console.WriteLine($"{iterations}: " + s);
}, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount });
await singleTestFlow.Completion;
var completionTask = singleTestFlow.Completion;
var message = $"action block: {iterations} ";
switch (completionTask.Status)
{
case TaskStatus.RanToCompletion:
message += "ran to completion";
break;
case TaskStatus.Canceled:
message += "was canceled";
break;
case TaskStatus.Faulted:
message += "has faulted";
Console.WriteLine(completionTask.Exception);
break;
}
Console.WriteLine(message);
iterations++;
}
}
}
}
Der Punkt in der Konsole, wo i "eee" eingetragen ist, wo der Screenshot bemängelt Block Debug genommen wurde.
Wow danke für die Hilfe! Es funktioniert jetzt. Von Ihrer Antwort habe ich zwei neue Fragen. Was ist der Unterschied zwischen dem Warten auf 'singleTestFlow.Completion' und' Task.WhenAny (singleTestFlow.Completion) '?Letzteres lässt meinen Code funktionieren, aber ich verstehe den Unterschied nicht. Zweitens, wie könnte ich die von 'Task.Run (RestartActionBlock) 'zurückgegebene Aufgabe verwenden? Ich möchte nicht auf die Fertigstellung warten, denn ich brauche den Rest des Codes in main weiter. – Slvrfn
Wenn Sie Ihre 'RestartActionBlock' Aufgabe für immer laufen wollen, müssen Sie sicherstellen, dass es umfassende Ausnahmebehandlung eingebaut hat. Wenn' erwarten singleTestFlow.Completion' eine Ausnahme auslöst (aufgrund des Blockfehlers), 'RestartActionBlock' kehrt sofort zurück (ähnlich wie eine synchrone Methode würde). Es geht nie über das 'Warten' hinaus. Mit "Task.WhenAny" können Sie das umgehen, weil es lediglich einen Verweis auf die erste abgeschlossene (oder fehlerhafte) Aufgabe zurückgibt. Es wirft keine Ausnahmen zurück. Der Effekt ist ähnlich wie "try/catch" um "await singleTestFlow.Completion" zu setzen. –
Hatten Sie einen Verweis auf die 'Task' gehalten zurück von' Task.Run (RestartActionBlock) ', würden Sie, dass irgendwann bemerken Übergänge es Zustand Faulted, und folgern, dass Ihre' RestartActionBlock' Schleife beendet haben müssen. Dies würde Ihnen beim Debuggen helfen. Fakt ist, dass ich persönlich das Problem mit einigem Erfolg diagnostizierte. –