{"id":32323,"date":"2006-02-10T10:00:00","date_gmt":"2006-02-10T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2006\/02\/10\/the-dangers-of-sleeping-on-a-ui-thread\/"},"modified":"2006-02-10T10:00:00","modified_gmt":"2006-02-10T10:00:00","slug":"the-dangers-of-sleeping-on-a-ui-thread","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20060210-00\/?p=32323","title":{"rendered":"The dangers of sleeping on a UI thread"},"content":{"rendered":"<p>\nIf you have a thread that owns a window,\nyou should not be using the\n<code>Sleep<\/code> function,\nbecause that causes your thread to stop responding\nto messages for the duration of the sleep.\nThis is true even for sleeps of short duration,\nsuch as sleeping for a few seconds and waking up\nin order to poll the state of something in the system.\nAs we noted earlier,\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2006\/01\/24\/516808.aspx\">\npolling is bad for system performance<\/a>,\nimpairing the system&#8217;s ability to conserve energy\nin low power scenarios and suffering from the\nmagnifying effects of Terminal Server.\nIf you&#8217;re idle, stay idle.\nIf you&#8217;re busy, do your work and then go idle.\n<\/p>\n<p>\nUnfortunately, I occasionally see code like the\nfollowing:\n<\/p>\n<pre>\n<i> \/\/ code in italics is wrong\n \/\/ bad polling message loop\n bool fQuit = false;\n while (!fQuit) {\n  Sleep(2000);\n  CheckIfSomethingHappened();\n  MSG msg;\n  while (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE)) {\n   if (msg.message == WM_QUIT) {\n    fQuit = true;\n    break;\n   }\n   TranslateMessage(&amp;msg);\n   DispatchMessage(&amp;msg);\n  }\n }\n ...<\/i>\n<\/pre>\n<p>\nObserve that this message loop goes up to two seconds without\nprocessing messages.\nPeople aren&#8217;t crazy enough to insert two-second sleeps into\nthreads that are responsible for interacting with the end user,\nbut they often do it for background worker threads which\ncreated hidden windows for cross-thread communication purposes.\nSince the thread has no visible UI,\nhanging for a few seconds at a time is invisible to the end user.\n<\/p>\n<p>\nUntil it isn&#8217;t.\n<\/p>\n<p>\nIf the system needs to broadcast a message,\nit will have to wait for this sleeping thread to finally wake up\nand process the broadcast message.\nIn the meantime, the component that is issuing the broadcast\ncontinues to wait.\nFor example, the user may have double-clicked a document that\nrequires DDE to open.\nThe DDE process begins with a broadcast of the\n<code>WM_DDE_INITIATE<\/code> message,\nwhich stalls behind your window.\nYour non-responsive hidden window has just created a\n&#8220;Windows seems to hang for a few seconds at random intervals&#8221; bug.\n<\/p>\n<p>\nNote that many people overlook that calling\n<code>CoInitialize<\/code> (possibly indirectly)\nto initialize a thread for STA\ncreates a hidden window in order to perform marshalling.\nConsequently, a thread that is running in a single-threaded\napartment must pump messages.\nFailing to do so will result in mysterious system-wide stalls\ndue to the unresponsive window.\n<\/p>\n<p>\nBut what if you want to sleep for a period of time while processing\nmessages?\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2006\/01\/26\/517849.aspx\">\nWe looked at this a little while ago<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you have a thread that owns a window, you should not be using the Sleep function, because that causes your thread to stop responding to messages for the duration of the sleep. This is true even for sleeps of short duration, such as sleeping for a few seconds and waking up in order to [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-32323","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>If you have a thread that owns a window, you should not be using the Sleep function, because that causes your thread to stop responding to messages for the duration of the sleep. This is true even for sleeps of short duration, such as sleeping for a few seconds and waking up in order to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/32323","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=32323"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/32323\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=32323"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=32323"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=32323"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}