C# - windows 表单 - 如何从任务中捕获未处理的异常
C# - windows form - how to catch an unhandled exception from a task
我正在使用 BCrypt Nuget 程序包创建一个 windows 具有一定加密功能的表单应用程序。该包使用 "Verify" 方法来检查密码和散列。 "Verify" 方法 returns 如果密码和散列 match.I 试图通过在调用 "Verify" 方法时执行一些操作来向表单添加一些功能,则该方法 returns 为真。
所以我将它用作一项任务,当我使用以“$2$”开头的适当 bcrypt 哈希作为要比较的输入时,代码工作正常。但是当给出随机输入时,程序包识别出一个无效的盐并且程序包抛出 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);
}
}
}
异常未处理,因为它是在一个线程(线程池线程,ContinueWith
运行)中抛出的,但您在另一个线程(GUI 线程)中捕获它。
我强烈建议使用 .NET 4.5(或带有 Microsoft.Bcl.Async 包的 .NET 4)附带的 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
捕获 any 异常然后抛出 [=15= 听起来不是个好主意](你还说这个异常是抛出的'by package'其实是你自己抛出的)。允许传播任何异常会更好:
isMatch = await Task.Run(
() =>
{
return BCrypt.Net.BCrypt.Verify(
(String)txtPlainPasswordCheck.Text,
(String)txtHashedPasswordCheck.Text)
);
}
);
我正在使用 BCrypt Nuget 程序包创建一个 windows 具有一定加密功能的表单应用程序。该包使用 "Verify" 方法来检查密码和散列。 "Verify" 方法 returns 如果密码和散列 match.I 试图通过在调用 "Verify" 方法时执行一些操作来向表单添加一些功能,则该方法 returns 为真。
所以我将它用作一项任务,当我使用以“$2$”开头的适当 bcrypt 哈希作为要比较的输入时,代码工作正常。但是当给出随机输入时,程序包识别出一个无效的盐并且程序包抛出 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);
}
}
}
异常未处理,因为它是在一个线程(线程池线程,ContinueWith
运行)中抛出的,但您在另一个线程(GUI 线程)中捕获它。
我强烈建议使用 .NET 4.5(或带有 Microsoft.Bcl.Async 包的 .NET 4)附带的 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
捕获 any 异常然后抛出 [=15= 听起来不是个好主意](你还说这个异常是抛出的'by package'其实是你自己抛出的)。允许传播任何异常会更好:
isMatch = await Task.Run(
() =>
{
return BCrypt.Net.BCrypt.Verify(
(String)txtPlainPasswordCheck.Text,
(String)txtHashedPasswordCheck.Text)
);
}
);