Winforms visual studio ide按暂停按钮会在运行时停止,而不是在我想要的位置?

Winforms visual studio ide按暂停按钮会在运行时停止,而不是在我想要的位置?,winforms,visual-studio-2010,debugging,Winforms,Visual Studio 2010,Debugging,我终于决定在stackoverflow上问一些困扰了我很长时间的问题: 为什么在调试模式下执行Windows窗体项目时,当我单击“暂停”按钮时,它总是在应用程序上停止运行 Application.Run(new FormGuiV2()); // pressing pause stops here 这对我来说似乎是个缺陷。为什么它不停在实际执行的代码行上?在调试时,在堆栈顶部停止是没有帮助的。我想我一定是错误地使用了调试器 为了绕过它,我必须知道正在执行哪些代码行,并放置调试点,这很容易出错,

我终于决定在stackoverflow上问一些困扰了我很长时间的问题:

为什么在调试模式下执行Windows窗体项目时,当我单击“暂停”按钮时,它总是在应用程序上停止运行

 Application.Run(new FormGuiV2()); // pressing pause stops here
这对我来说似乎是个缺陷。为什么它不停在实际执行的代码行上?在调试时,在堆栈顶部停止是没有帮助的。我想我一定是错误地使用了调试器

为了绕过它,我必须知道正在执行哪些代码行,并放置调试点,这很容易出错,有时需要花费时间来跟踪我要放置调试点的位置

我想知道单击暂停按钮并使其实际停止在代码执行行的正确方法


谢谢

启动应用程序的主线程将位于
应用程序。运行
,否则应用程序将关闭。
Application.Run
启动UI线程,可能还有其他线程,这就是您的预期位置

应用程序的主线程是调试器始终跳转到的位置。这是应该始终存在的一个线程,否则进程将关闭

当您打开Debug->Windows->Threads窗口时,您可以切换到其他线程,您将看到其中一个线程实际上暂停在您可能期望的位置


请参阅:

启动应用程序的主线程将位于
应用程序。请运行
,否则应用程序将关闭。
Application.Run
启动UI线程,可能还有其他线程,这就是您的预期位置

应用程序的主线程是调试器始终跳转到的位置。这是应该始终存在的一个线程,否则进程将关闭

当您打开Debug->Windows->Threads窗口时,您可以切换到其他线程,您将看到其中一个线程实际上暂停在您可能期望的位置

请参阅:

这很可能是正在执行的实际代码行

实际上,
应用程序.Run
方法中的代码正在执行,但该代码是.NET Framework库的一部分,您没有启用.NET源代码单步执行。如果你这样做了,它会把你扔到WinForms库代码迷宫中的某个地方,你可能也不会觉得这很有帮助

这个谜团背后的秘密是Windows应用程序大部分时间都在循环中等待,等待来自操作系统的基于用户输入和其他事件的消息。这就是所谓的。NET框架(和其他框架)为您将这些内容抽象出来,在内部处理这些消息,并以其他方式(例如,通过引发事件)向您公开重要内容。但这一切仍在幕后进行

为了随机点击“暂停”按钮并在某个地方插入用户代码,您必须对其进行计时。大多数情况下,当您中断执行时,代码处于“空闲”状态,等待用户输入或其他操作。因此,断点通常是一种更好、更易于管理的方法。

这很可能是正在执行的实际代码行

实际上,
应用程序.Run
方法中的代码正在执行,但该代码是.NET Framework库的一部分,您没有启用.NET源代码单步执行。如果你这样做了,它会把你扔到WinForms库代码迷宫中的某个地方,你可能也不会觉得这很有帮助

这个谜团背后的秘密是Windows应用程序大部分时间都在循环中等待,等待来自操作系统的基于用户输入和其他事件的消息。这就是所谓的。NET框架(和其他框架)为您将这些内容抽象出来,在内部处理这些消息,并以其他方式(例如,通过引发事件)向您公开重要内容。但这一切仍在幕后进行


为了随机点击“暂停”按钮并在某个地方插入用户代码,您必须对其进行计时。大多数情况下,当您中断执行时,代码处于“空闲”状态,等待用户输入或其他操作。因此,断点通常是一种更好、更易于管理的方法。

事实并非如此,当您发出Debug+Break命令时,它会在激活的任何代码处停止。可以在调试器的调用堆栈窗口中看到。您中断自己执行的任何代码的几率都很小,但您的程序99%的时间都在等待Windows告诉它发生了什么有趣的事情。这使得调用堆栈通常看起来像:

    [Managed to Native Transition]  
    System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData) + 0x444 bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context) + 0x155 bytes  
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x4a bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm) + 0x31 bytes  
>   WindowsFormsApplication1.exe!WindowsFormsApplication1.Program.Main() Line 16 + 0x1d bytes   C#
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x6b bytes    
    Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x27 bytes  
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x6f bytes   
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0xa7 bytes  
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x16 bytes  
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x41 bytes    
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes   
    [Native to Managed Transition]  
请注意FPushMessageLoop()方法如何位于堆栈跟踪的顶部。这是Windows GUI应用程序中著名的消息循环,它接收Windows通知。如果您还启用了非托管调试,那么您将看到更多,核心GetMessage()winapi函数是消息循环的重要部分

注意堆栈跟踪中的
标记。这就是你所说的代码行。您之所以看到它,是因为上面的代码是.NET framework的一部分。如果你没有安装参考源,你就没有它的源代码

因此,调试器只是沿着堆栈向下走,寻找要显示的任何相关源代码。并且不可避免地会出现在Program.cs中的Main()方法中,即Application.Run()调用


要在GUI应用程序中获得有用的中断,需要设置断点。

如果不设置断点,则在您发出Debug+Break命令时,它会在激活的任何代码处停止。可以在调试器的调用堆栈窗口中看到。你打断的可能性