2013-05-17 12 views
5

Zwykle dla kodu, w którym nie oczekuję wyjątków, ale robi (tj. Błąd programowania), chcę, aby aplikacja uległa awarii (aby "uszkodzone dane, zgłosić nieprawidłowe dane użytkownikowi itp.".Uzyskiwanie nieoczekiwanego zadania Wyjątek w celu usunięcia aplikacji wcześniej niż zbieranie śmieci

Czy istnieje dobra praktyka uzyskiwania (bliższe) tego zachowania podczas korzystania z Tasks? Zarejestrowaliśmy program obsługi dla TaskScheduler.UnobservedTaskException. Problem polega na tym, że może się to zdarzyć później, niż później, powodując nieoczekiwany wyjątek.

Pytanie: Która opcja należy używać jeśli:

  1. Mam owinąć moje działanie Task s w try/catch i eskalować w połowu wyjątków nie oczekuję? A jeśli tak, to co należy zrobić, aby eskalować (tj Chciałbym aby zmusić go do ognia zdarzenie AppDomain.UnhandledException i zakończyć.

  2. powinienem dołączyć kontynuację (OnlyOnFaulted) na wątku UI (jest to aplikacja WinForm), który ponownie generuje wyjątek, jeśli nie jest oczekiwana wyjątek

  3. Czy jest lepszy lub bardziej standardowe podejście

Oto co # 1 może wyglądać tak:?

var t1 = Task.Factory.StartNew(() => 
    { 
     try 
     { 
      string path = null; // Programming error. Should have been a valid string. Will cause System.ArgumentNullException below 
      using (FileStream fs = File.Create(path)) 
      { 

      } 
     } 
     catch (System.IO.IOException) { throw; } // Expected possible exception 
     catch (System.UnauthorizedAccessException) { throw; } 
     catch 
     { 
      // Anything caught here is not an expected exception and should be escalated. 
      // But how? 
     } 
    }); 

Oto co # 2 może wyglądać następująco:

TaskScheduler uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 
var t1 = Task.Factory.StartNew(() => 
    { 
     string path = null; // Programming error. Should have been a valid string. Will cause System.ArgumentNullException below 
     using (FileStream fs = File.Create(path)) 
     { 

     } 
    }); 

t1.ContinueWith(t => 
    { 
     Exception ex = t.Exception; 
     if (ex is IOException || ex is UnauthorizedAccessException) // Expected exceptions (do nothing) 
      return; 

     throw ex; // Not expected (escalate by rethrowing) 

    }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, uiTaskScheduler); 

Odpowiedz

2

Mocowanie kontynuację czuje się dobrym podejściem do mnie. Jeśli nie masz nic przeciwko założeniu, że nie będziesz blokował wątku UI zbyt długo z innych powodów, zmuszanie kontynuacji do działania w wątku UI wydaje mi się bardzo rozsądną opcją. W ten sposób możesz wykonać dowolne zadania interfejsu użytkownika, jako część awaryjnego wyłączenia.

Powiązane problemy