2016-03-11 54 views
0

使用BCrypt Nuget包創建一個帶有一些加密的Windows窗體應用程序。該軟件包使用「驗證」方法來檢查密碼和散列。如果密碼和哈希匹配,「驗證」方法返回true。我試圖通過在調用「驗證」方法時執行某些操作來添加一些功能。C# - 窗體窗體 - 如何捕捉任務中未處理的異常

所以我用它作爲一個任務,當我使用以「$ 2 $」作爲輸入進行比較的正確的bcrypt散列時,代碼工作正常。但是,當給定隨機輸入時,程序包會識別出一個無效的salt,並且saltParseException被程序包拋出,程序崩潰並顯示該異常未處理。我嘗試添加一個saltParaseException處理,但它仍然無法工作。因爲它是在一個線程中拋出

private void btncheckPassword_Click(object sender, EventArgs e) 
    { 
     bool isMatch = false; 
     if(txtPlainPasswordCheck.TextLength > 0 && txtHashedPasswordCheck.TextLength > 0) 
     { 
      try 
      { 
       var Task_VerifyPassword = Task.Factory.StartNew(() => BCrypt.Net.BCrypt.Verify((String)txtPlainPasswordCheck.Text, (String)txtHashedPasswordCheck.Text)); 
       Task_VerifyPassword.ContinueWith(t => { throw new BCrypt.Net.SaltParseException(); }, TaskContinuationOptions.OnlyOnFaulted); 
       SetCursor(Cursors.WaitCursor); 
       isMatch = Task_VerifyPassword.Result; 
      } 
      catch (BCrypt.Net.SaltParseException e2) 
      { 
       SetCheckLabel(e2.Message.ToString(), Color.Red, Color.Black); 

      } 
      if (isMatch) 
      { 
       SetCheckLabel("Passwords Match", Color.Black, Color.Green); 
       SetCursor(Cursors.Default); 
      } 
      else 
      { 
       SetCheckLabel("Passwords Don't Match", Color.Red, Color.Black); 
       SetCursor(Cursors.Default); 
      } 
     } 
    } 

回答

2

異常是未處理(線程池中的線程,在其上運行ContinueWith),但你正趕上它在另一個(GUI線程)。

我強烈建議使用.NET 4.5(或.NET 4與Microsoft.Bcl.Async包)附帶的async-await idiom的所有好處。有了它,處理從異步方法拋出的異常就非常自然,並且在捕獲的SynchronisationContext上繼續執行(在await之後的代碼)。你可以寫這樣的事情:

private async void btncheckPassword_Click(object sender, EventArgs e) 
{ 
    if(txtPlainPasswordCheck.TextLength > 0 && txtHashedPasswordCheck.TextLength > 0) 
    { 
     bool isMatch = false; 
     SetCursor(Cursors.WaitCursor); 

     try 
     { 
      isMatch = await Task.Run(
      () => 
       { 
       try 
       { 
        return BCrypt.Net.BCrypt.Verify(
         (String)txtPlainPasswordCheck.Text,      
         (String)txtHashedPasswordCheck.Text) 
        ); 
       } 
       catch 
       { 
        throw new BCrypt.Net.SaltParseException(); 
       } 
       } 
      ); 

      if (isMatch) 
      { 
       SetCheckLabel("Passwords Match", Color.Black, Color.Green); 
      } 
      else 
      { 
       SetCheckLabel("Passwords Don't Match", Color.Red, Color.Black);  
      } 
     } 
     catch (BCrypt.Net.SaltParseException e2) 
     { 
      SetCheckLabel(e2.Message.ToString(), Color.Red, Color.Black); 
     } 

     SetCursor(Cursors.Default); 
    } 
} 

注:我不熟悉BCrypt庫,但它聽起來並不像一個好主意,趕上任何例外,從Verify,然後扔BCrypt.Net.SaltParseException(你甚至說,這拋出異常「按包裝」,但你實際上是在拋出它)。這將是更好,讓任何異常的傳播:

isMatch = await Task.Run(
    () => 
    { 
     return BCrypt.Net.BCrypt.Verify(
     (String)txtPlainPasswordCheck.Text,      
     (String)txtHashedPasswordCheck.Text) 
    ); 
    } 
); 
+0

謝謝[鏈接](http://imgur.com/7lnYAhz) ,像變魔術一樣,我只是沒有指定任何參數catch語句。 – Zee