Rozważmy następujący „wystrzel i zapomnij” przypadek użycia:Wyjątek przenoszenia ognia i zapomnieć o C# 5 (w .NET 4.5)
Dzwoniący prosi niektórych danych z mojej metody. Moja metoda sprawdza pamięć podręczną, aby sprawdzić, czy dane już tam są. Jeśli nie, pobiera go ze źródła i zapisuje w pamięci podręcznej. Osoba dzwoniąca nie musi czekać na pojawienie się buforowania przed uzyskaniem wyników, a metoda nie powinna uniemożliwiać wywołującemu uzyskania wyniku, jeśli buforowanie zakończy się niepowodzeniem. Co mam dziś wygląda tak:
public Foo GetFoo(string fooKey)
{
// look for Foo with fooKey in cache
// if Foo is not found, get Foo with fooKey from source
// and assign it to local variable myFoo
Task cacheTask
= Task.Run
(
() => CacheFoo(myFoo)// fire-and-forget the caching of myFoo
);
return myFoo;
}
Jeśli CacheFoo zgłasza wyjątek to idzie nie zauważony i ostatecznie (w .NET 4.5) to zostaje wchłonięty przez ramy. Wolałbym raczej zrobić ostatnie zdjęcie, aby samemu usunąć wyjątek, ale nie chcę blokować bieżącego wątku. Jaki jest najlepszy sposób na zrobienie tego?
Oto co próbowałem
try
{
...
cacheTask.ContinueWith
(
(e) => {
if (cacheTask.IsFaulted)
{
/* log cacheTask.Exception */;
}
}
, TaskContinuationOptions.OnlyOnFaulted
);
}
Czy istnieje lepszy sposób? Czy potrzebuję instrukcji "if" na IsFaulted lub czy jest to zbędne, ponieważ już określiłem "OnlyOnFaulted"?
Wszelkie opinie/sugestie będą mile widziane.
Byłoby miło, gdyby można oznaczyć zadanie jako fire-and-forget..so bez Wait/ContinueWith możliwe. A ponieważ w tym przypadku nie ma nikogo, kto mógłby poradzić sobie z tym wyjątkiem, powinien on zawiesić aplikację, aby mieć ładny plik zrzutu, w którym można oglądać lokalne zmienne i stertę w momencie, w którym wyjątek został zgłoszony ... – mmmmmmmm