Mam metodę asynchroniczną zwracającą zadanie.Wzorzec do implementacji metod synchronizacji w kontekście zadania nierównoległego (tłumaczenie/rozpakowywanie wyjątków AggregateException)
Chciałbym również zaoferować synchroniczny odpowiednik, ale nie chcę, aby konsumenci z niego musieli rozpakowywać się AggregateException
s.
Teraz rozumiem, że cała idea polega na tym, że nie można arbitralnie wybrać jednego w sposób ogólny, i wiem, że mógłbym przeczytać więcej ładunków artykułów Stephena Touba (będę, ale nie teraz) i zrozumiem to wszystko i może sam decydować.
W międzyczasie chcę użyć faktu, że moje zadania są w rzeczywistości przykręcone "workflow" bez równoległości, po prostu interweniując Waits (nie, nie TPL DataFlow), które nie powinny skutkować więcej niż jednym wyjątkiem. W takim przypadku należałoby obsługiwać w następujący sposób:
CallAsync().Wait();
}
catch(AggregateException ae)
{
throw ae.Flatten().First()
czy mam zagwarantowane, że AggregateException
zawsze ma InnerException
nawet jeśli jest ich więcej niż jeden. A może jest przypadek, w którym powinienem wrócić do .Flatten().First()
?
W niektórych OC docs, widzę odniesienie do metody Unwrap()
na AggregateException
(nie wiem, czy to rozszerzenie lub coś w wersji beta).
Jako zastępczy, robię:
void Call()
{
try
{
CallAsync().Wait();
}
catch (AggregateException ex)
{
var translated = ex.InnerException ?? ex.Flatten().InnerExceptions.First();
if (translated == null)
throw;
throw translated; }
}
Task CallAsync(){ ...
Dzięki; specjalnie dla punktu straty stosu, który rozważałem, a następnie przymykałem oko (nie wiem nawet, czy normalna sztuczka PreserveStackTrace zadziała, ponieważ jestem pod średnim zaufaniem, więc nie mogę nawet próbować). Ostatnie pytanie (i mój prawdziwy punkt wyjścia) - jakikolwiek pomysł, dlaczego większość próbek używa '.InnerException' zamiast' .Flatten(). InnerExceptions.First() 'lub inny sposób rozpakowania - ** są one równoważne lub nie **? Jeśli tak, to wszelkie odniesienia? Czy istnieją inne sposoby rozpakowywania - wszelkie linki są doceniane ... –
Jeśli spojrzysz na konstruktory AggregateException z ILDasmhem, zobaczysz, że ostatecznie istnieje prywatny konstruktor (string, IList), który jest delegowany do innych implementacji i w tym konstruktorze wywołują konstruktor bazowy Exception przekazujący pierwszy wyjątek w IList jako parametr innerException. Jednakże, ponieważ pierwszy wyjątek może technicznie być kolejnym wyjątkiem AggregateException, użycie Flatten() jest gwarantowanym sposobem uzyskania pierwszego wyjątku leżącego u podstaw nieagregacyjnego wyjątku. –
Fajnie, to doskonale wyjaśniłem. Chciałbym, aby jedna z 50 stron dokumentów i artykułów mogła wyjaśnić to jako udaną. (Nie mam jeszcze na TPL z dekompilatorem - z jakiegoś powodu uważam to za umysłowo poza granicami.Co do tego jak wyjaśniam nie przyjmując takiego stosunku do WCF ...: D) –