{"id":229670,"date":"2020-06-15T09:00:37","date_gmt":"2020-06-15T16:00:37","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/visualstudio\/?p=229670"},"modified":"2020-06-23T11:11:44","modified_gmt":"2020-06-23T18:11:44","slug":"debugging-async-code-parallel-stacks-for-tasks","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/visualstudio\/debugging-async-code-parallel-stacks-for-tasks\/","title":{"rendered":"Debugging Async Code: Parallel Stacks for Tasks"},"content":{"rendered":"<p>In the <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/how-do-i-debug-async-code-in-visual-studio\/\">last async debugging blog post<\/a>, we explored several tools in Visual Studio to help you debug your async code.\u00a0 One of the tools we discussed was the <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/debugger\/using-the-parallel-stacks-window?view=vs-2019\">Parallel Stacks window<\/a> for Tasks (or Parallel Tasks), a tool that provides task and thread information while debugging.\u00a0 Unlike the tabular <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/debugger\/using-the-tasks-window?view=vs-2019\">Task<\/a> and <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/debugger\/how-to-use-the-threads-window?view=vs-2019\">Thread<\/a> windows, this information is presented graphically, displaying the relationships between threads and tasks, like an illustrative version of a call stack.\u00a0 In the latest version of Visual Studio, we\u2019ve made some major improvements to the Parallel Tasks window for .NET applications, so let\u2019s do a deep dive into the updated feature!<\/p>\n<p>The code we\u2019ll be using to demonstrate the Parallel Tasks tool can be found at <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/debugger\/walkthrough-debugging-a-parallel-application?view=vs-2019\">this in-depth Microsoft documentation walkthrough on async debugging tools<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<h4><strong>Why use the Task View in the Parallel Stacks window?<\/strong><\/h4>\n<p>The \u201cmagic\u201d of asynchronous programming in .NET can be both a blessing and a curse.\u00a0 The additions of\u00a0 the <em>Task<\/em> type, <em>async,<\/em> and <em>await <\/em>\u00a0in .NET provide an extra layer of abstraction, which enable you to write responsive applications but also make it harder to navigate through and understand the status of each awaiting or active task while debugging.\u00a0 The Parallel Stacks window (Debug &gt; Windows &gt; Parallel Stacks, select \u201cTasks\u201d dropdown) is a great way to help you visualize and better navigate through the execution of your async code.<\/p>\n<p>It\u2019s common to break up the async code into blocks that are scheduled after another piece of code is completed.\u00a0 The Threads view in the Parallel Stacks window can tell you when a code block isn&#8217;t running on a thread. Unlike the Tasks view, however, it won&#8217;t help you determine\u00a0<em>why\u00a0<\/em>a code block isn&#8217;t running.<\/p>\n<p><figure id=\"attachment_229680\" aria-labelledby=\"figcaption_attachment_229680\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"wp-image-229680 size-medium\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_BasicExample-300x219.png\" alt=\"Basic Parallel Tasks window example\" width=\"300\" height=\"219\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_BasicExample-300x219.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_BasicExample-768x561.png 768w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_BasicExample.png 806w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><figcaption id=\"figcaption_attachment_229680\" class=\"wp-caption-text\"><em>Figure 1: Basic Parallel Tasks window example<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<p>An awaited Task and the code scheduled to run after it don\u2019t share a direct caller-callee relationship (such as a call stack on a thread).\u00a0 Instead, they have a &#8220;logical&#8221; relationship. This is where each piece of code knows about the next scheduled block, creating a &#8220;logical stack&#8221;.\u00a0 Figure 2 shows three tasks sharing a call stack at the start of the program, thus sharing the same box.<\/p>\n<p>If an async method is &#8220;active&#8221; (i.e. it is running on a thread), these logical stacks are sometimes displayed in the Threads view.\u00a0 However, the Tasks view will show both active and awaiting logical stacks. This is helpful for debugging hangs or figuring out why your particular task or code block is not running.<\/p>\n<p><figure id=\"attachment_229682\" aria-labelledby=\"figcaption_attachment_229682\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"size-full wp-image-229682\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_Figure2_TaskView.png\" alt=\"Figure 2: Parallel Stacks window - Task View\" width=\"808\" height=\"589\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_Figure2_TaskView.png 808w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_Figure2_TaskView-300x219.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_Figure2_TaskView-768x560.png 768w\" sizes=\"(max-width: 808px) 100vw, 808px\" \/><figcaption id=\"figcaption_attachment_229682\" class=\"wp-caption-text\"><em>Figure 2: Parallel Stacks window &#8211; Task View<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<h4><strong>How is the new Parallel Tasks window <\/strong><strong>structured?<\/strong><\/h4>\n<p>At any given program state, tasks sharing the same logical call stack are grouped into boxes\/nodes.\u00a0 These nodes reveal how many tasks are doing the same operations before branching out to different functions.\u00a0 As a result, this grouping can provide a clearer picture of the whole program\u2019s state.<\/p>\n<p>By default, Parallel Tasks displays a top-down display for task progression, branching from the most recent function call to the initial caller.\u00a0 Using the reverse layout button in the Parallel Task window&#8217;s toolbar gives you a bottom-up display for task progression.\u00a0 This reverse layout shows tasks branching from an initial caller to the most recent function call.\u00a0 In Figure 3, three tasks branch from function S.C to three different call stacks, with their most recent calls being S.R, S.O, and S.M, respectively.<\/p>\n<p><figure id=\"attachment_229681\" aria-labelledby=\"figcaption_attachment_229681\" class=\"wp-caption alignnone\" ><img decoding=\"async\" class=\"size-full wp-image-229681\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_BottomUp_Branching.png\" alt=\"Task View bottom-up layout\" width=\"808\" height=\"595\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_BottomUp_Branching.png 808w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_BottomUp_Branching-300x221.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_BottomUp_Branching-768x566.png 768w\" sizes=\"(max-width: 808px) 100vw, 808px\" \/><figcaption id=\"figcaption_attachment_229681\" class=\"wp-caption-text\"><em>Figure 3: Task View bottom-up layout<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<h4><strong>What else is new in the Parallel Tasks Window?<\/strong><\/h4>\n<p>Hovering over each line in the window and view the tabular representation of all the tasks currently in that method.\u00a0 Like the Task Window, this table lets you view the status, ID, duration, and more specific info of each Task.\u00a0 Selecting a task will now direct you to its corresponding async call stack.\u00a0 You can use this call stack to navigate to related code and inspect local variables within your async methods.<\/p>\n<p><figure id=\"attachment_229687\" aria-labelledby=\"figcaption_attachment_229687\" class=\"wp-caption alignnone\" ><img decoding=\"async\" class=\"size-full wp-image-229687\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_TaskHover.gif\" alt=\"Hovering over a task in the Parallel Stacks window\" width=\"1908\" height=\"950\" \/><figcaption id=\"figcaption_attachment_229687\" class=\"wp-caption-text\"><em>Figure 4: Hovering over a task in the Parallel Stacks window<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<p><figure id=\"attachment_229688\" aria-labelledby=\"figcaption_attachment_229688\" class=\"wp-caption alignnone\" ><img decoding=\"async\" class=\"wp-image-229688 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_CallStack2.gif\" alt=\"Accessing a task's async call stack\" width=\"1908\" height=\"950\" \/><figcaption id=\"figcaption_attachment_229688\" class=\"wp-caption-text\"><em>Figure 5: Accessing a task&#8217;s async call stack<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<p>For multi-threaded applications, you may want to navigate between a specific task and the thread running that task.\u00a0 Now, you can quickly jump between tasks in the Tasks View and their corresponding threads in the Threads View via the context menu.<\/p>\n<p><figure id=\"attachment_229689\" aria-labelledby=\"figcaption_attachment_229689\" class=\"wp-caption alignnone\" ><img decoding=\"async\" class=\"size-full wp-image-229689\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_GoToThread-1.gif\" alt=\"Swap between threads and tasks in Parallel Stacks\" width=\"1908\" height=\"950\" \/><figcaption id=\"figcaption_attachment_229689\" class=\"wp-caption-text\"><em>Figure 6: Swap between threads and tasks in Parallel Stacks<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<p>You&#8217;ll also receive notifications about tasks waiting on locks owned by specific threads or threads waiting on specific async operations to complete.\u00a0 When this happens, you can double-click the notification to navigate directly to that thread or task.<\/p>\n<p>Finally, you can save the Parallel Stacks window contents as a PNG file using the save icon in the window&#8217;s toolbar.<\/p>\n<p><figure id=\"attachment_229683\" aria-labelledby=\"figcaption_attachment_229683\" class=\"wp-caption alignnone\" ><img decoding=\"async\" class=\"size-full wp-image-229683\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_Save.png\" alt=\"Parallel Stacks save icon\" width=\"800\" height=\"91\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_Save.png 800w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_Save-300x34.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/PST_Save-768x87.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption id=\"figcaption_attachment_229683\" class=\"wp-caption-text\"><em>Figure 7: Parallel Stacks save icon<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<h4><strong>Ready to try the new and improved Parallel Tasks window while debugging your asynchronous code?\u00a0 Give us your feedback!<\/strong><\/h4>\n<p>There are still plenty of improvements we can make in future versions of this tool. Your feedback will help us do that!\u00a0 If you\u2019d like to share your experience using the improved Parallel Stacks tool or debugging async code in general, <a href=\"https:\/\/www.research.net\/r\/87JXND5\">please complete this survey<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Want a visual depiction of how your async code is executing in Visual Studio? Check out the newly updated Parallel Stacks for Tasks window!<\/p>\n","protected":false},"author":651,"featured_media":229623,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[155],"tags":[237,6398,9,6427,12,475],"class_list":["post-229670","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-visual-studio","tag-net","tag-async","tag-debug","tag-parallel-stacks","tag-visual-studio","tag-visual-studio-2019"],"acf":[],"blog_post_summary":"<p>Want a visual depiction of how your async code is executing in Visual Studio? Check out the newly updated Parallel Stacks for Tasks window!<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/229670","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/users\/651"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/comments?post=229670"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/229670\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media\/229623"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media?parent=229670"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/categories?post=229670"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/tags?post=229670"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}