{"id":107416,"date":"2022-11-16T07:00:00","date_gmt":"2022-11-16T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=107416"},"modified":"2022-11-16T06:18:32","modified_gmt":"2022-11-16T14:18:32","slug":"20221116-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20221116-00\/?p=107416","title":{"rendered":"Why won&#8217;t C++\/WinRT let me <CODE>co_await<\/CODE> a <CODE>CoreDispatcher<\/CODE> or <CODE>DispatcherQueue<\/CODE>?"},"content":{"rendered":"<p>A customer was trying to use a <code>Core\u00adDispatcher<\/code> to switch threads, but they couldn&#8217;t get it to work:<\/p>\n<pre>winrt::fire_and_forget MyPage::OnExternalEvent()\r\n{\r\n    auto lifetime = get_strong();\r\n\r\n    \/\/ this doesn't compile\r\n    co_await Dispatcher();\r\n\r\n    \/\/ neither does this\r\n    co_await winrt::resume_foreground(Dispatcher());\r\n\r\n    ...\r\n}\r\n<\/pre>\n<p>Performing a direct <code>co_await<\/code> on a <code>Core\u00adDispatcher<\/code> or <code>Dispatcher\u00adQueue<\/code> <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/uwp\/cpp-and-winrt-apis\/concurrency-2\"> appears to be commonplace<\/a>, but for some reason, this customer couldn&#8217;t get it to work:<\/p>\n<pre style=\"white-space: pre-wrap;\">error C2338: Not an awaitable type (compiling source file {sourceFile}.cpp)\r\nsee reference to function template instantiation 'decltype(auto) winrt::impl::get_awaiter&lt;T&gt;(T &amp;&amp;) noexcept' being compiled\r\nwith\r\n[\r\n    T=winrt::Windows::UI::Core::CoreDispatcher\r\n] (compiling source file {sourceFile}.cpp)\r\n<\/pre>\n<p>If they used the <code>resume_<wbr \/>foreground<\/code> helper function, they got<\/p>\n<pre style=\"white-space: pre-wrap;\">error C3861: 'resume_foreground': identifier not found\r\n<\/pre>\n<p>That second error message is a very strong clue that some definition is missing.<\/p>\n<p>The problem is that they broke one of the rules of C++\/WinRT: If you want to use a Windows Runtime object, you must include the header file for the namespace that contains the object.<\/p>\n<p>In this case, they failed to <code>#include &lt;winrt\/Windows.UI.Core.h&gt;<\/code>. It is the namespace header that defines the operations that can be performed on the object. In the case of <code>Core\u00adDispatcher<\/code>, the namespace header defines is what provides <code>co_await<\/code> and <code>resume_<wbr \/>foreground<\/code> support.<\/p>\n<p>Similar logic applies to the case of <code>co_await<\/code>&#8216;ing a <code>Dispatcher\u00adQueue<\/code>.<\/p>\n<p>The customer confirmed that including the required header file solved the problem.<\/p>\n<p><b>Bonus chatter<\/b>: Another possibility is that you get<\/p>\n<pre style=\"white-space: pre-wrap;\">error C2664: 'winrt::resume_foreground::awaitable winrt::resume_foreground(const winrt::Windows::System::DispatcherQueue &amp;,const winrt::Windows::System::DispatcherQueuePriority) noexcept': cannot convert argument 1 from 'winrt::Windows::UI::Core::CoreDispatcher' to 'const winrt::Windows::System::DispatcherQueue &amp;'\r\n<\/pre>\n<p>This is what happens when you include the header file for some other dispatcher, but you forgot to include the header file for the dispatcher you actually want to use. The compiler sees the <code>resume_<wbr \/>foreground<\/code> function, but the overload that you want isn&#8217;t there because you forgot to include the header file that provides it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Making sure you meet the usual prerequisites.<\/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-107416","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Making sure you meet the usual prerequisites.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107416","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=107416"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107416\/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=107416"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=107416"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=107416"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}