Laden...

TPL Dataflow Lib: Faulted TransformBlock fortführen

Erstellt von unconnected vor 8 Jahren Letzter Beitrag vor 8 Jahren 2.193 Views
unconnected Themenstarter:in
849 Beiträge seit 2006
vor 8 Jahren
TPL Dataflow Lib: Faulted TransformBlock fortführen

Hallo,

ich beschäftige mich gerade mit der TPL Dataflow Library.

Mein Szenario verlangt das wenn was schief geht (Exception) auf jeden Fall mit den nächsten zu verarbeitenden Items weitergemacht werden soll, und das Fehlerhafte Item geloggt und dann weggeworfen wird.

Nun scheint das Standard verhalten des TransformBlock zu sein bei jeder Exception in den Faulted State zu gehen, und dann seine Arbeit einzustellen. Ist es möglich diesen dazu zu bewegen (vllt im ContinueWith) das Item aus seiner Queue zu löschen und weiter zu machen?

Oder muss ich tatsächlich schon für diesen nicht unüblichen Vorgang einen eigenen Block implementieren?

742 Beiträge seit 2005
vor 8 Jahren

Ich würde mir um dein Item ein Container bauen und dann selber catchen:


class ProcessItem<T>
{
   T Result { get; set; }

   Exception { get; set; }
}

16.807 Beiträge seit 2008
vor 8 Jahren

Ich hab mal vor Ewigkeiten was damit gemacht; daher nagel mich bitte nicht fest 😃
Bin der Meinung, dass man bei Custom Fault Handling einen eigenen TransformBlock definieren und dort das Fault-Interface (IDataflowBlock.Fault(Exception exception)) überschreiben bzw. eigenimplementieren muss.

unconnected Themenstarter:in
849 Beiträge seit 2006
vor 8 Jahren

@malignate

stimmt daran hatte ich auch schon gedacht, nur wird dieser dann auch durch alle Blöcke durchgeschleust, ohne das wirklich was gemacht wird.

Ich hatte mir schon gedacht das ich hier meinen eigenen TB bauen muss 😦

Falls noch jemand ne Idee hat, immer raus damit 😃

Danke

W
955 Beiträge seit 2010
vor 8 Jahren

Na so schwer ist es ja auch nicht einen Filter hinter dem Block zu verwenden und die fehlerhaften in einem ActionBlock auszusieben.

unconnected Themenstarter:in
849 Beiträge seit 2006
vor 8 Jahren

Stimmt schwer nicht, aber aufwendig wenn man das öfter verwenden will.

Dann muss ich in jedem Block Exception Handling betreiben, und danach noch filtern.
Das möchte ich nicht, oder nur ungern.

unconnected Themenstarter:in
849 Beiträge seit 2006
vor 8 Jahren

So noch ein wenig mehr wühlen in Google und lesen von x Tutorials bin ich nun so verblieben das ich den TransformManyBlock für meine Bedürfnisse "missbrauche".

Ich habe mir zu diesem Zweck eine kleine Helper klasse gebaut:


 public static Func<TInput, IEnumerable<TOutput>>  BuildTransformManyFunc<TInput, TOutput>(Func<TInput, TOutput> func,Action<TInput> logAction = null)
        {
            var retfunc = new Func<TInput, IEnumerable<TOutput>>(data =>
            {
                try
                {
                    var result = func(data);
                    return new TOutput[] {result};

                }
                catch
                {
                    if (logAction != null)
                        logAction(data);

                    return new TOutput[] {};
                }

            });

            return retfunc;
        }

usage:


var step= new TransformManyBlock<string, string>(TransformBlockFuncHelper.BuildTransformManyFunc<string,string>(uri =>
            {
return uri + "Step1";
                
            }),new ExecutionDataflowBlockOptions
            {
                MaxMessagesPerTask = ExecutionDataflowBlockOptions.Unbounded,
                MaxDegreeOfParallelism = ExecutionDataflowBlockOptions.Unbounded
            });

ich denke hiermit kann ich nun leben. Die Transform Aufgaben, die mit einer Exception enden werden einfach als leeres IEnumerable zurück gegeben.