C#-windows窗体-如何捕获任务中未处理的异常
我使用BCrypt Nuget包创建了一个带有加密的windows窗体应用程序。包使用“验证”方法检查密码和哈希。如果密码和散列匹配,“Verify”方法将返回true。我试图在调用“Verify”方法时执行一些操作,从而为表单添加一些功能 因此,我将其用作一项任务,当我使用以“$2$”开头的适当bcrypt哈希作为比较输入时,代码正常工作。但是当一个随机输入被给出时,包识别出一个无效的salt,并且包抛出一个saltParseException,程序崩溃,错误提示异常未被处理。我尝试添加一个SaltparaseeException处理,但仍然不起作用C#-windows窗体-如何捕获任务中未处理的异常,c#,winforms,exception-handling,task-parallel-library,C#,Winforms,Exception Handling,Task Parallel Library,我使用BCrypt Nuget包创建了一个带有加密的windows窗体应用程序。包使用“验证”方法检查密码和哈希。如果密码和散列匹配,“Verify”方法将返回true。我试图在调用“Verify”方法时执行一些操作,从而为表单添加一些功能 因此,我将其用作一项任务,当我使用以“$2$”开头的适当bcrypt哈希作为比较输入时,代码正常工作。但是当一个随机输入被给出时,包识别出一个无效的salt,并且包抛出一个saltParseException,程序崩溃,错误提示异常未被处理。我尝试添加一个S
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);
}
}
}
异常未处理,因为它被抛出到一个线程(线程池线程,在该线程上运行
ContinueWith
),但您正在另一个线程(GUI线程)上捕获它
我强烈建议使用.NET4.5(或.NET4和Microsoft.Bcl.async包)附带的AsyncWait习惯用法的所有优点。有了它,处理异步方法抛出的异常就变得非常自然,并且在捕获的SynchronizationContext上执行continuation(在wait
之后的代码)。你可以这样写:
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库,但从验证捕获任何异常,然后抛出BCrypt.Net.SaltParseException
(您甚至说这个异常是“由包”抛出的,但实际上是您自己抛出的)听起来不是个好主意。最好允许传播任何异常:
isMatch = await Task.Run(
() =>
{
return BCrypt.Net.BCrypt.Verify(
(String)txtPlainPasswordCheck.Text,
(String)txtHashedPasswordCheck.Text)
);
}
);
异常未处理,因为它被抛出到一个线程(线程池线程,在该线程上运行ContinueWith
),但您正在另一个线程(GUI线程)上捕获它
我强烈建议使用.NET4.5(或.NET4和Microsoft.Bcl.async包)附带的AsyncWait习惯用法的所有优点。有了它,处理异步方法抛出的异常就变得非常自然,并且在捕获的SynchronizationContext上执行continuation(在wait
之后的代码)。你可以这样写:
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库,但从验证捕获任何异常,然后抛出BCrypt.Net.SaltParseException
(您甚至说这个异常是“由包”抛出的,但实际上是您自己抛出的)听起来不是个好主意。最好允许传播任何异常:
isMatch = await Task.Run(
() =>
{
return BCrypt.Net.BCrypt.Verify(
(String)txtPlainPasswordCheck.Text,
(String)txtHashedPasswordCheck.Text)
);
}
);
谢谢你,像魔术一样工作,我只是没有为catch语句指定任何参数。谢谢你,像魔术一样工作,我只是没有为catch语句指定任何参数。