C/WinRT是微软为窗口运行时提供的现代C17语言投影.2018年引入.窗口SDK版本10.0.17134.0(Windows101803).这里不介绍CWinRT其他,只介绍它提供的异步能力:异步操作方法假设我有个耗时很久的方法,我不希望它阻塞UI线程,那你可这样:#includedispatcherqueue.h#includewinrt/base.h#includewinrt/Windows.System.h#includewinrt/Windows.Foundation.hwinrt::Windows::Foundation::IAsyncActionreadImg(){co_awaitwinrt::resume_background();//这里省略了耗时很长的逻辑代码co_awaitwinrt::resume_foreground(dq);}这里,winrt::Windows::Foundation::IAsyncAction代表一个无结果,无进度的异步操作.除此外,WinRT提供了如下异步操作类型:类型返回值进度报告使用场景IAsyncAction无无简单异步操作IAsyncActionWithProgress无有需要进度反馈的操作IAsyncOperation有无返回结果的异步操作IAsyncOperationWithProgress有有返回结果且需进度的操作如果要在一个方法中使用co_await操作异步逻辑,则你就要按co_await兼容的方法标记该方法,比如返回IAsyncAction类型.co_await winrt::resume_background()是C/WinRT提供的切换线程的助手函数,来从当前线程切换到后台线程(背后有线程池).该操作是非阻塞的.co_await winrt::resume_foreground(dq)负责从后台线程切换到当前线程.是不是比C标准库里的异步操作要简单的多呢?dq是什么?线程任务调度对象winrt::Windows::System::DispatcherQueue dq是C/WinRT中用来管理线程任务调度的核心类,它管理按偏爱级排列的任务队列,确保在线程上串行执行任务.该类型的对象有以下特点:1,每线程最多有1个DispatcherQueue2,可向该线程投递异步任务3,任务按优先级排队执行4,依赖线程消息循环(MessageLoop)在启动应用时,就创建了管理UI线程的任务队列的该dq对象.winrt::Windows::System::DispatcherQueue dq;dq{winrt::Windows::System::DispatcherQueue::GetForCurrentThread()}在WinUI3或UWP项中,用上述代码就可直接得到dq.传统的Win32项,必须要提前执行如下逻辑,才能得到dq.(DispatcherQueue不是Win32线程的默认组成部分)winrt::init_apartment(winrt::apartment_type::single_threaded);DispatcherQueueOptions options{sizeof(DispatcherQueueOptions),DQTYPE_THREAD_CURRENT,DQTAT_COM_STA};staticwinrt::Windows::System::DispatcherQueueController controller{nullptr};autohrCreateDispatcherQueueController(options,reinterpret_castABI::Windows::System::IDispatcherQueueController**(winrt::put_abi(controller)));不要掐死UI线程假设有如下用来取剪切板内文本的异步代码.IAsyncOperationwinrt::hstringUtil::getTextFromClipboard(){autoviewClipboard::GetContent();if(view.Contains(StandardDataFormats::Text())){co_returnco_awaitview.GetTextAsync();}co_returnL;}如果如下取剪切板内的文本autostrgetTextFromClipboard().get();此时可能会报如下错误:这是因为:1,.get()阻塞当前线程等待异步完成2,异步操作内部需要调度到UI线程执行Clipboard,API(操作剪切板的API的要求)3,但你阻塞了当前UI线程(.get()没返回)4,无法运行消息循环,无法调度5,WinRT检测到该UI线程无法响应,则抛!is_sta_thread.方案就是不要掐死UI线程autostrOpUtil::getTextFromClipboard2();strOp.Completed([this](autoconstsender,autostatus){autostrsender.GetResults();});或使用co_await调用getTextFromClipboard方法,来把这段逻辑也包在IAsyncAction方法中.