{"id":229629,"date":"2020-06-11T09:00:22","date_gmt":"2020-06-11T16:00:22","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/visualstudio\/?p=229629"},"modified":"2020-06-11T10:42:50","modified_gmt":"2020-06-11T17:42:50","slug":"how-do-i-debug-async-code-in-visual-studio","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/visualstudio\/how-do-i-debug-async-code-in-visual-studio\/","title":{"rendered":"How Do I Debug Async Code in Visual Studio?"},"content":{"rendered":"<p>In a <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/how-do-i-think-about-async-code\/\">recent post<\/a>, we explored the basics of asynchronous code, why it\u2019s important, and how to write it in C#.\u00a0 However, while it can improve your program\u2019s overall throughput, async code is still not exempt from bugs!\u00a0 Writing async code makes debugging more difficult when potential deadlocks, vague error messages, and finding which task(s) are causing a bug are thrown into the mix.\u00a0 Luckily, Visual Studio has several new and old features compatible with managed, native, and JavaScript to help ease your frustrations with debugging async code.\u00a0 Let\u2019s take a tour!<\/p>\n<p>&nbsp;<\/p>\n<h4><strong>Where can I see all my program\u2019s tasks?<\/strong><\/h4>\n<p>When you encounter a bug in your async code, you probably want to identify all your Tasks and determine which of them are causing the error.\u00a0 If you\u2019ve debugged multithreaded applications, you may be familiar with the <strong>Threads <\/strong>window.\u00a0 Good news, there\u2019s also equivalent window for tasks!\u00a0 The <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/debugger\/using-the-tasks-window?view=vs-2019\"><strong>Tasks <\/strong>window<\/a> allows you to view all your tasks, displaying their IDs, current locations, the method originally passed into each of them, and their current statuses (active, scheduled, blocked, or deadlocked) at break time.\u00a0 If your program is multithreaded, this window will also display the threads running each task. This can help to identify specific threads which may also be contributing to an issue.<\/p>\n<p>You can access the <strong>Tasks <\/strong>window at <strong>Debug &gt; Windows &gt; Task <\/strong>or by using <strong>CTRL+SHIFT+D, K<\/strong>.<\/p>\n<p><figure id=\"attachment_229638\" aria-labelledby=\"figcaption_attachment_229638\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"size-full wp-image-229638\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/TasksWindow.png\" alt=\"Tasks window\" width=\"869\" height=\"412\" \/><figcaption id=\"figcaption_attachment_229638\" class=\"wp-caption-text\"><em>Tasks window<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<h4><strong>How can I locate the origin of a thrown exception in my async code?<\/strong><\/h4>\n<p>Determining a thrown exception&#8217;s original location is frustrating when debugging async code.\u00a0 When an exception is thrown multiple times, Visual Studio typically returns the call stack where the exception was most recently thrown via the Exception Helper.\u00a0 Unfortunately, this isn\u2019t always helpful for async debugging.\u00a0 To fix this, we\u2019ve implemented <strong>rethrown exceptions<\/strong> in 16.4.\u00a0 With this update, the Exception Helper displays the original call stack when an exception is rethrown.\u00a0 To learn more about this new feature, check out <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/exception-helper-rethrown-exceptions\/\">Andy Sterland\u2019s blog post<\/a>.<\/p>\n<p><figure id=\"attachment_229661\" aria-labelledby=\"figcaption_attachment_229661\" class=\"wp-caption alignnone\" ><img decoding=\"async\" class=\"wp-image-229661 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/RethrownException-Copy.png\" alt=\"Rethrown exception example\" width=\"729\" height=\"466\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/RethrownException-Copy.png 729w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/RethrownException-Copy-300x192.png 300w\" sizes=\"(max-width: 729px) 100vw, 729px\" \/><figcaption id=\"figcaption_attachment_229661\" class=\"wp-caption-text\"><em>Rethrown exception example<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<h4><strong>Is there a way to better visualize tasks and async code flow?<\/strong><\/h4>\n<p>For a graphical depiction of async code&#8217;s execution, Visual Studio has the <strong>Parallel Stacks <\/strong>window for threads and tasks.\u00a0 Improved for Visual Studio 16.6, the Parallel Stacks window for tasks (or <strong>Parallel Tasks <\/strong>window) visually displays active, awaiting, and scheduled tasks and how they relate to each other.\u00a0 Double-clicking an active or awaiting task shows the async call stack in the <strong>Call Stack<\/strong> window. To understand which thread is running a specific task, you can swap between the Parallel Threads and Parallel Tasks windows. You can do this by right-clicking and selecting <strong>Go To Thread <\/strong>in the context menu.\u00a0 To learn more about the new updates made to <strong>Parallel Tasks <\/strong>in 16.6<strong>, <\/strong>stay tuned for an upcoming blog post\u2026<\/p>\n<p><figure id=\"attachment_229662\" aria-labelledby=\"figcaption_attachment_229662\" class=\"wp-caption alignnone\" ><img decoding=\"async\" class=\"size-full wp-image-229662\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/ParallelTask_TourExample-Copy.png\" alt=\"Parallel Stacks for Tasks window\" width=\"1141\" height=\"799\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/ParallelTask_TourExample-Copy.png 1141w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/ParallelTask_TourExample-Copy-300x210.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/ParallelTask_TourExample-Copy-1024x717.png 1024w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2020\/06\/ParallelTask_TourExample-Copy-768x538.png 768w\" sizes=\"(max-width: 1141px) 100vw, 1141px\" \/><figcaption id=\"figcaption_attachment_229662\" class=\"wp-caption-text\"><em>Parallel Stacks for Tasks window<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<h4><strong>Ready to use these tools to debug your async code?<\/strong><\/h4>\n<p>Now that you have more tools in your belt to help you debug your code, share your feedback with us!\u00a0 Reaching out with your thoughts and feature suggestions will help us create the best async debugging experience.<\/p>\n<p>You can also check out <a href=\"https:\/\/www.youtube.com\/watch?v=aVEug50YpaM\">this new video on async debugging tools in Visual Studio<\/a> for more demos.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Debugging async code is challenging.  Let&#8217;s explore some Visual Studio tools that can help you debug your async programs easier!<\/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,6399,9,287,12,475],"class_list":["post-229629","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-visual-studio","tag-net","tag-async","tag-asynchronous","tag-debug","tag-tips-and-tricks","tag-visual-studio","tag-visual-studio-2019"],"acf":[],"blog_post_summary":"<p>Debugging async code is challenging.  Let&#8217;s explore some Visual Studio tools that can help you debug your async programs easier!<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/229629","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=229629"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/229629\/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=229629"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/categories?post=229629"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/tags?post=229629"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}