{"id":103657,"date":"2020-04-08T07:00:00","date_gmt":"2020-04-08T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=103657"},"modified":"2020-04-08T06:32:29","modified_gmt":"2020-04-08T13:32:29","slug":"20200408-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200408-00\/?p=103657","title":{"rendered":"Creating a non-agile delegate in C++\/WinRT, part 3: The other cases and why they aren&#8217;t interesting"},"content":{"rendered":"<p>We&#8217;ve been looking at one specific case of a non-agile delegate, namely a delegate that is invoked on a background thread and wants to execute synchronously on a UI thread. What about the other cases?<\/p>\n<p>Yeah, what about them? Let&#8217;s write out a table.<\/p>\n<table style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th rowspan=\"2\">Handled on<\/th>\n<th colspan=\"2\">Raised on<\/th>\n<\/tr>\n<tr>\n<th>Background thread<\/th>\n<th>UI thread<\/th>\n<\/tr>\n<tr>\n<th>Background thread<\/th>\n<td>Already there<\/td>\n<td>Makes no sense<\/td>\n<\/tr>\n<tr>\n<th>UI thread<\/th>\n<td rowspan=\"2\"><code>resume_<\/code><code>synchronous<\/code><\/td>\n<td>Already there<\/td>\n<\/tr>\n<tr>\n<th>Other UI thread<\/th>\n<td><code>resume_<\/code><code>synchronous<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Two of the boxes are labeled <i>Already there<\/i>. Those are the cases where the event is raised in the same apartment that you want to handle it, in which case everything is fine and there&#8217;s no need to play any apartment-switching games.<\/p>\n<p>Two of the boxes are labeled <code>resume_<\/code><code>synchronous<\/code>. In these cases, you want to run the handler synchronously on a UI thread which is not the one your handler was invoked in. In those cases, you can use the <code>resume_<\/code><code>synchronous<\/code> function we discussed last time. Of course, since you are running on a UI thread, you shouldn&#8217;t perform long blocking operations. This is particularly true if you&#8217;re in the bottom right corner, because you are holding <i>two<\/i> UI threads hostage while your event handler is running.<\/p>\n<p>That leaves the last box, labeled <i>Makes no sense<\/i>.<\/p>\n<p>That box makes no sense.<\/p>\n<p>That box represents the case where the event is raised on a UI thread, but you want to handle it synchronously on a background thread. Why would you do that?<\/p>\n<p>The usual reason for moving to a background thread is to allow you to perform long-running operations without affecting the responsiveness of the UI thread. But that doesn&#8217;t help us here, because this table is about running the code <i>synchronously<\/i> in another apartment, so the UI thread is going to remain unresponsive while the background thread does its work. Switching to the background thread didn&#8217;t accomplish anything. You may as well just do it on the UI thread.<\/p>\n<p>Remember that this entire discussion is in the context of running the handler synchronously. If you can run the handler asynchronously, perhaps with the assistance of a deferral, then you should just do that.<\/p>\n<p>We&#8217;ll wrap up this discussion next time by connecting this discussion to C++\/WinRT in a different way.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We handled only one case, but that&#8217;s the only one worth handling.<\/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-103657","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>We handled only one case, but that&#8217;s the only one worth handling.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103657","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=103657"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103657\/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=103657"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=103657"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=103657"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}