【问题标题】:C# – try{}catch(Exception ex){} – do NOT caught any exception [duplicate]C# – try{}catch(Exception ex){} – 不捕获任何异常 [重复]
【发布时间】:2023-03-29 16:00:01
【问题描述】:

短版,这个方法:

public override async void MethodWithException()
{
    throw new Exception("any EXCEPTION type and format will be skipped by outer try-catch block");
}

未被此块捕获(“catch”被跳过):

try
{
    realClassFromAbstractObject.MethodWithException();

    Console.WriteLine("Output in the console – NOT POSSIBLE but true!");

}
catch (Exception exception)
{

     //Nothing caught!
     Console.WriteLine("2. Nothing in console, skipped exception! " + exception); //--- Notihng in the output

}

这是非常奇怪的行为。

完整版:请看一下我制作的简短演示:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("1. Program starts"); //+++ Yes, in the console
        RealClassFromAbstract realClassFromAbstractObject = new RealClassFromAbstract();


        Task.Factory.StartNew(() =>
        {
            try
            {


                //Next method should to throw an exception! But nothing!
                realClassFromAbstractObject.MethodWithException();



                Console.WriteLine("In the console too – NOT POSSIBLE but true!"); //+++ Yes, in the console

            }
            catch (Exception exception)
            {

                //Nothing caught!
                Console.WriteLine("2. Nothing in console, skipped exception! " + exception); //--- Notihng in the output

            }
        }).ConfigureAwait(false);



        Console.WriteLine("3. Program ends"); //+++ Yes, in the console
        Console.ReadKey();
    }
}

abstract class AbstractClass
{
    public abstract void MethodWithException();
}

class RealClassFromAbstract : AbstractClass
{
    public override async void MethodWithException()
    {
        throw new Exception("any EXCEPTION type and format will be skipped by outer try-catch block");
        throw new ArgumentException();
        throw new DivideByZeroException();


        //Anythig else, await....
    }
}

这是来自真实项目的简化示例。如果您对如何使 catch 块像往常一样再次工作有任何建议,请告诉我。谢谢! 这是第一次,catch 块有这种奇怪的行为。

下载:console application demo project – https://www.dropbox.com/s/x8ta7dndbijxbvq/ConsoleAppExceptionTryCatchProblem.zip?dl=1(请不要调试运行,以便立即看到结果)

【问题讨论】:

  • 我的精神力量告诉我,您需要在拨打realClassFromAbstractObject.MethodWithException()之前输入await
  • @RadosławCybulski 这是我的第一个猜测,但不幸的是,这并没有帮助,错误列表中有两个错误:“'await' 运算符只能在异步 lambda 表达式中使用。考虑标记这个带有 'async' 修饰符的 lambda 表达式。”和“不能等待'void'”。
  • 使你的类异步或使用返回任务中的.Result

标签: c# exception try-catch


【解决方案1】:

感谢大家的回答,尤其是@MickyD 提供了与文章的链接

答案:避免异步无效explanations - https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

如果有人遇到同样的问题,修复代码,用 cmets 进行所有更改:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("1. Program starts"); //+++ Yes, in the console
        RealClassFromAbstract realClassFromAbstractObject = new RealClassFromAbstract();


        Task.Factory.StartNew(async () =>//CHANGE 1/5: async lambda
        {
            try
            {
                //CHANGE 2/5: await
                await realClassFromAbstractObject.MethodWithException();


                Console.WriteLine("Nothing in the console, that's correct"); //--- Notihng in the console

            }
            catch (Exception exception)
            {
                Console.WriteLine("2. Nice, exception! " + exception); //+++ Yes, in the console!

            }
        }).ConfigureAwait(false);



        Console.WriteLine("3. Program ends"); //+++ Yes, in the console
        Console.ReadKey();
    }
}

abstract class AbstractClass
{
    //CHANGE 3/5: returned type is Task
    public abstract Task MethodWithException();
}

class RealClassFromAbstract : AbstractClass
{
    //CHANGE 4/5: returned type is Task according to the abstact class
    public override async Task MethodWithException()
    {
        throw new Exception("This exception would be caught by outer try-catch block");


        //Anythig else, await....
        await Task.Delay(3);


        //CHANGE 5/5: await or:
        return;//or "Task.CompletedTask" in .NET >=4.6 if no awaits or Task.FromResult() in .NET <4.6
    }
}

在实际项目中,那部分代码确实很旧。第一个版本是同步的 -> 第二个版本与 BackgroundWorker 一起工作 -> 在直接线程之后并且仅在 ->– 任务之后,但在异步/等待之前。 在最后阶段,开发过程中出现了错误。

最有趣的是,一切都运行了至少两年,没有出现任何问题。我上周在测试时遇到了奇怪的应用程序级别异常。 非常感谢您的所有回答!

【讨论】:

  • 不客气。 +1。 :)
猜你喜欢
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
  • 2012-08-06
  • 1970-01-01
  • 2015-06-21
  • 2011-05-27
  • 1970-01-01
相关资源
最近更新 更多