2015-04-24 3 views
5

Sto provando a catturare un'eccezione generata, ma non bolle fino a dove è stata chiamata. Si rompe in InsertNewUser 'blocco catch s, dicendoL'eccezione non fa bolle

"un'eccezione di tipo 'System.Exception' si è verificato in PeakPOS.exe ma non è stata gestita nel codice utente"

Se clicco su debugger Continua, va a un file chiamato App.g.i.cs e si interrompe su una riga che non capisco ma ha qualcosa a che fare con il debug in pausa. L'applicazione termina dopo.

Perché si dice che l'eccezione non è gestita quando viene ricontrollata e quindi ri-catturata e gestita (da gestire)?


AccessViewModel.cs

public void SaveNewUser(Popup popup) 
{ 
    UserAccounts.Add(TempUser); 

    string salt = PeakCrypto.GenerateSalt(); 
    string hash = PeakCrypto.GenerateHashedPassword(Password + salt); 
    try 
    { 
     PeakDB.InsertNewUser(TempUser, salt, hash); 
    } 
    catch (Exception e) 
    { 
     //TODO notify user that new account could not be saved 
    } 

    CreateNewAccount(); 

    if (popup != null) 
     popup.IsOpen = false; 
} 

PeakDB.cs

public static async void InsertNewUser(UserAccount user, String salt, String hash) 
{ 
    var db = await DatabaseHelper.GetDatabaseAsync(); 

    try 
    { 
     using (var userStatement = await db.PrepareStatementAsync(
      "INSERT INTO AccessAccounts (FirstName, LastName, Salt, Hash) VALUES(@first, @last, @salt, @hash)")) 
     { 
      userStatement.BindTextParameterWithName("@first", user.FirstName); 
      userStatement.BindTextParameterWithName("@last", user.LastName); 
      userStatement.BindTextParameterWithName("@salt", salt); 
      userStatement.BindTextParameterWithName("@hash", hash); 
      await userStatement.StepAsync(); 
     } 
    } 
    catch(Exception e) 
    { 
     // TODO: log the exception error 
     throw; 
    } 
} 

App.g.i.cs

#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION 
    UnhandledException += (sender, e) => 
    { 
     if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break(); 
    }; 
#endif 
+0

Hai provato a deselezionare la casella di controllo "Interruzione quando si verifica questa eccezione" ed eseguire di nuovo? Penso che mentre si trova in modalità di debug si interrompa eccezionalmente –

+0

@Saagar: Sì. Quello che succede è che va al file App.g.i.cs e si interrompe sull'istruzione if proprio come prima, semplicemente non si rompe più nel fermo. Mi chiedo se sto fraintendendo try/catch. Sta rilevando un'eccezione che non la gestisce? – ShrimpCrackers

risposta

4

Questo comportamento è previsto per l'operazione async. Il tuo codice gestisce/intercetta le eccezioni generate dalla parte sincrona del metodo, ma lascia gestire l'intera applicazione per gestire la parte asincrona.

È possibile osservare il comportamento previsto se si lancia esplicitamente un'eccezione sulla prima riga del metodo InsertNewUser (parte sincrona).

Correzione: correttamente await il metodo async.

// must return at least `Task` to be awaitable 
public static async Task InsertNewUser(... 

E rispetto await il metodo (si noti che "asincrona è virale" - Async/Await Best Practices):

try 
    { 
     await PeakDB.InsertNewUser(TempUser, salt, hash); 
    } 
    catch (Exception e) ... 

O almeno .Wait se console app (WPF/WinForm/Asp.Net sarà un punto morto - await vs Task.Wait - Deadlock?):

try 
    { 
     PeakDB.InsertNewUser(TempUser, salt, hash).Wait(); 
    } 
    catch (Exception e) ... 

Se non si può fare sia - almeno usare una corretta Fire-and-forget with async vs "old async delegate" per chiamare il metodo async void S.

Nota: async void è una cattiva pratica e deve essere utilizzata solo per eventi di tipo.

+0

Grazie, Alexei. Ha funzionato. Apprezzo i collegamenti da quando sono nuovo a C# e ho solo una breve descrizione asincrona/attendi e non la capisco molto bene. – ShrimpCrackers

+0

@ShrimpCrackers welcome.Se hai bisogno di lavorare con 'async' /' await' ti consiglio vivamente di analizzare le risposte migliori di [Stephen Cleary] (http://stackoverflow.com/users/263693/stephen-cleary) prima di fare qualsiasi lavoro serio in questo la zona. –