2016-03-11 21 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