gpt4 book ai didi

c# - 为什么第一个代码立即显示错误消息,但第二个不

转载 作者:行者123 更新时间:2023-11-30 15:20:23 26 4
gpt4 key购买 nike

假设我们有两次按钮点击:

private void button2_Click(object sender, EventArgs e)
{
using (
System.Threading.Tasks.Task t = new System.Threading.Tasks.Task(() => {
throw new Exception("puzzle");

}))
{
t.Start();
}
}

private void button3_Click(object sender, EventArgs e)
{
System.Threading.Tasks.Task t = new System.Threading.Tasks.Task(() => {
throw new Exception("puzzle");

});
t.Start();
}

如果在没有调试的情况下使用按钮的这两个事件处理程序运行程序,则 button2_Click 会立即导致错误消息出现。但是 button3_Click 不会导致错误消息立即出现。我的印象是,如果 Task 被垃圾收集,那么它会抛出异常。如果 Task 没有被垃圾回收,则会生成异常,但会保留在一些有趣的地方。我试图在 MSDN 上找到一些很好的例子,但不是很幸运。

最佳答案

我可以看到其他按钮处理程序抛出错误。如果您在 VS IDE 中启用Just My Code(工具-> 选项-> 调试-> 常规)

,这对您来说很明显

在我解释为什么您可以从 button2 处理程序中看到错误而从 button3 中看不到错误之前,了解 .NET 如何处理任务异常是有意义的。

首先,您的两个 Task 操作都会抛出异常,而这些操作将被您的代码未处理。对于Task,用户代码抛出的任何未处理的异常都会以AggregateException的形式传播回调用线程;并且仅当您在此 TaskWait(在这种情况下是异常)或对其调用 Result 以获取输出时,才会引发此异常。在您的情况下,您没有执行任何这些操作,因此您的异常不会被注意到。但这些异常仍然存在,直到任务被垃圾收集,并将根据 .NET 异常策略升级。 TaskScheduler.UnobservedTaskException 是您想要覆盖异常升级时需要研究的内容。

现在回到您的处理程序;

如果是 button2 :您要求在开始任务后立即执行确定性破坏(using block)。这意味着,您的任务可能处于 WaitingToRunWaitingForActivationRunningRunning 等状态。根据 MSDN,只有当任务处于完成状态(RanToCompletion、Faulted 或 Canceled)时,它才可以被释放。 话虽如此,异常可能并非在所有情况下都很明显,因为它取决于您的任务状态和确定性破坏开始的时刻。

在 button3 的情况下: 您不是自己处理 Task 而是让垃圾收集器为您执行此操作。这就是为什么您看不到任何异常的原因。我希望您清楚如何为您处理异常。

MSDN详细解释了 .NET 中如何处理 TASK 异常及其涵盖多种场景。

关于c# - 为什么第一个代码立即显示错误消息,但第二个不,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40271626/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com