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?
Ich würde mir um dein Item ein Container bauen und dann selber catchen:
class ProcessItem<T>
{
T Result { get; set; }
Exception { get; set; }
}
ImageTools for Silverlight: http://imagetools.codeplex.com | http://www.silverdiagram.net | http://www.cleancodedeveloper.de b:::
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.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
@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
Na so schwer ist es ja auch nicht einen Filter hinter dem Block zu verwenden und die fehlerhaften in einem ActionBlock auszusieben.
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.
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.