视觉工作室ide按下暂停按钮停在RUN而不是我想要的地方?

时间:2013-07-12 21:46:40

标签: winforms visual-studio-2010 debugging

长期困扰我的东西我终于决定在stackoverflow问这里:

为什么在DEBUG模式下执行Windows窗体项目时,单击暂停按钮时它将始终停在 Application.Run 上?

 Application.Run(new FormGuiV2()); // pressing pause stops here

这对我来说似乎是一个缺陷。为什么它不会暂停在正在执行的代码行上?调试时,在堆栈顶部停止是没有用的。我想我必须错误地使用调试器?

为了解决这个问题,我必须知道正在执行哪些代码行并放置一个调试点,这很容易出错并且有时很耗费时间来追踪我想放置调试点的位置。

我想知道点击暂停按钮的正确方法,并让它实际停在执行的代码行。

由于

3 个答案:

答案 0 :(得分:6)

它没有,它在您给出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框架的一部分。如果您没有安装参考源,那么您就没有源代码。

因此,调试器只需向下移动堆栈,查找要显示的任何相关源代码。并且不可避免地会在Program.cs中的Main()方法中结束,即Application.Run()调用。

在GUI应用程序中获取有用的休息时间需要设置断点。

答案 1 :(得分:2)

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

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

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

请参阅:http://msdn.microsoft.com/en-us/library/w15yf86f.aspx

答案 2 :(得分:2)

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

实际上,正在执行Application.Run方法的内的代码,但该代码是.NET Framework库的一部分,并且您没有转换.NET源代码上。如果你这样做了,它会把你转移到WinForms库代码迷宫中的某个地方,你可能也找不到它。

这个谜团背后的秘密是Windows应用程序将大部分时间等待循环,等待来自操作系统的消息基于用户输入和其他事件。这称为message loop。 .NET Framework(以及其他框架)为您提取所有内容,在内部处理这些消息并以其他方式向您展示重要内容(例如,通过引发事件)。但它仍然在幕后进行。

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