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