{"id":23174,"date":"2006-09-28T04:29:00","date_gmt":"2006-09-28T04:29:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/maoni\/2006\/09\/28\/my-application-seems-to-hang-what-do-i-do-part-1\/"},"modified":"2021-10-04T16:34:25","modified_gmt":"2021-10-04T23:34:25","slug":"my-application-seems-to-hang-what-do-i-do-part-1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/my-application-seems-to-hang-what-do-i-do-part-1\/","title":{"rendered":"My application seems to hang. What do I do? \u2013 Part 1"},"content":{"rendered":"<p><P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">Defining \u201chang\u201d is a good place to start.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">When people say \u201chang\u201d they could mean all sorts of things. When I say \u201chang\u201d I mean the process is not making progress \u2013 the threads in the process are either blocked (eg. deadlocked, or not scheduled because of threads from other processes) or executing code (madly) but not doing useful work (eg. infinite loop, or busy spinning for a long time without doing useful work). The former uses no CPU while the later using 100% CPU. When a UI developer says \u201chang\u201d he could mean \u201cthe UI is not getting drawn\u201d so essentially they mean the UI threads are not working \u2013 other threads in their process could be doing lots of work but since the UI is not getting updated it appears \u201chang\u201d. So clarifying what you mean when you say \u201chang\u201d, which requires you to look at your process and its threads, is the first step.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">If you start Task Manager (taskmgr.exe) it shows you how much CPU each process is using <I>currently<\/I>. If you don\u2019t see a CPU column you can add it by clicking View\\Select Columns and check the \u201cCPU Usage\u201d checkbox.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">Note that if you have multiple CPUs, the CPU usage is at most 100. Let\u2019s say you have 4 CPUs and your process has one thread that\u2019s running and taking all the CPU it can you will see the CPU column for your process 25 \u2013 since your process can only use one CPU (at most to its full) at any given time.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">The CPU usage for a process is calculated as the CPU usage used by all the threads that belong to the process. Threads are what get to run on the CPUs. They get scheduled by the OS scheduler which decides when to run what thread on which processor. I won\u2019t cover the details here \u2013 the Windows Internals book by Russinovich and Solomon covers it.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">If you see your process is taking 0 CPU, that would explain why it\u2019s hung (for the period of time when the CPU keeps being 0) \u2013 no threads are getting to run in your process! The next thing to look at is the CPU usage of other processes. If you see one or multiple other processes that take up all the CPU that means the threads in your process simply don\u2019t get a chance to run \u2013 this is because the threads in those other processes are of higher priorities (or temporarily of higher priorities due to priority boosting) than the threads in your process. The possible causes are:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">1) there are threads that are marked as low priority which acquired locks that other threads in your process need in order to run. And the low priority threads are preempted by other (normal or high) prority threads from those other processes. This happens when people mistakenly use low priority threads to do \u201cunimportant work\u201d or \u201cwork that doesn\u2019t need to be done in a timely fashion\u201d without realizing that it\u2019s nearly impossible to avoid taking locks on those threads. I\u2019ve heard of many people say \u201cbut I am not taking a lock on my low priority threads\u201d which is not a valid argument because the APIs you call or the OS services you use can take locks in order to run your code \u2013 allocating on native NT heap can take locks; even triggering a page fault can take locks (which is not something an application developer can control in his code).<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">2) the threads in your process are of normal priority but those other processes have high priority threads \u2013 this should be relatively easy to diagnose (and unless some process is simply bad citizens this rarely happens) \u2013 you can take a look at what those processes are doing (again looking at their threads\u2019 callstacks is a good place to start).<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P><SPAN>That\u2019s&nbsp;all for today. Next time I will talk about other hang scenarios and techniques to debug them.<\/SPAN><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Defining \u201chang\u201d is a good place to start. &nbsp; When people say \u201chang\u201d they could mean all sorts of things. When I say \u201chang\u201d I mean the process is not making progress \u2013 the threads in the process are either blocked (eg. deadlocked, or not scheduled because of threads from other processes) or executing code [&hellip;]<\/p>\n","protected":false},"author":3542,"featured_media":58792,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685],"tags":[3011,108],"class_list":["post-23174","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","tag-maoniposts","tag-performance"],"acf":[],"blog_post_summary":"<p>Defining \u201chang\u201d is a good place to start. &nbsp; When people say \u201chang\u201d they could mean all sorts of things. When I say \u201chang\u201d I mean the process is not making progress \u2013 the threads in the process are either blocked (eg. deadlocked, or not scheduled because of threads from other processes) or executing code [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/23174","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/3542"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=23174"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/23174\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=23174"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=23174"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=23174"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}