为什么调试器会遇到默认情况?

Erw*_*n_H 5 c# debugging switch-statement

一些同事遇到了一个非常奇怪的调试问题,他单步执行开关,单步执行某些情况,但随后又遇到了默认情况。我不知道这怎么会发生!

它很容易重现,我终于将代码提取到一个小测试中。

如果我只在默认情况下设置断点,那么调试器将永远不会停在那里。但是如果我在case 42处添加断点,然后使用step over,之后会碰到default case!!请注意,尽管从未达到过捕获。所以调试器似乎显示了一些实际上没有发生的事情?另外,如果我删除异步任务并等待,那么它不会发生..我们还需要另一个声明变量的案例(花哨的东西,不是简单的整数等。)

public class Foo
{
    public readonly string Bar = nameof(Bar);
}

public async Task DoSomething(int x)
{
    try
    {
       switch (x)
       {
            case 43:
                var foo = new Foo();
                break;     
            case 42:
                Console.WriteLine(x);
                break;
            default:
                throw new NotImplementedException("aaarghh..");
        }
    }
    catch (Exception exc)
    {
        MessageBox.Show(exc.Message);
    }
}

private async void btnSomethingTo_Click(object sender, EventArgs e)
{
    await DoSomething(42);
}
Run Code Online (Sandbox Code Playgroud)

Sinatr 创建的 GIF 用于说明手头的主题,谢谢! 手头的问题

小智 -1

您未以正确的方式 使用DoSomething方法。ASYNC关键字意味着您在方法内的某个地方有一些等待调用(以在任务结束后稍后获得返回点),但您没有。您奇怪的调试器行为与实现有关。事实上,您的异常并未抛出。我已经重现了您的案例,并且MyException构造函数只是被调试器忽略/跳过,并且catch (Exception exc)部分中的代码也从未被调用。或者,如果我在CASE 42:中遇到中断,并且只需按 F5,那么将跳过 DEFAULT 部分中的断点。

public async Task DoSomething(int x)
        {
            try
            {
                switch (x)
                {
                    case 43:
                        var foo = new Foo();
                        break;
                    case 42:
                        Debug.WriteLine(x);
                        break;
                    case 44:
                        break;
                    default:
                        throw new MyException("aaarghh..");
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            await DoSomething(42);
        }

        public class MyException : Exception
        {
            public MyException(string message): base(message)
            {
                if (message != null)
                    Debug.WriteLine(message);
            }

            public MyException() : base()
            {
            }

            public MyException(string message, Exception innerException) : base(message, innerException)
            {
            }
        }
Run Code Online (Sandbox Code Playgroud)

  • 你说“*你没有以正确的方式使用DoSomething方法*”——我不认为“没有以正确的方式”与它有任何关系,这是我的观点 (2认同)