You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将IAsyncOperation转换为Task,如何正确实现AsTask扩展方法

现有实现的问题

你当前编写的AsTask扩展方法不符合异步规范,存在两个核心问题:

  • 直接调用IAsyncOperation<TResult>.GetResults()时,若WinRT异步操作还未完成,会直接抛出异常,且该调用是同步阻塞逻辑,完全失去异步非阻塞的优势
  • Task.FromResult仅能包装已完成的同步结果,没有实现对WinRT异步操作的生命周期监听逻辑
正确的实现方案

方案1:优先使用官方扩展(推荐)

如果你的项目是UWP、WinUI 3、.NET MAUI Windows平台等支持WinRT互操作的项目,不需要自行实现AsTask方法,直接引用System.Runtime.WindowsRuntime程序集,微软官方已经提供了全功能的生产级AsTask扩展,支持取消令牌、进度回调等多种重载,稳定性远高于自定义实现。

方案2:自定义实现AsTask扩展

如果你必须自行实现,可参考如下基于TaskCompletionSource的标准实现:

using Windows.Foundation;

public static class Helpers
{
    public static Task<TResult> AsTask<TResult>(this IAsyncOperation<TResult> source)
    {
        if (source == null)
            throw new ArgumentNullException(nameof(source));

        // 操作已完成时直接返回结果,避免额外分配
        if (source.Status == AsyncStatus.Completed)
        {
            return Task.FromResult(source.GetResults());
        }

        var completionSource = new TaskCompletionSource<TResult>();

        source.Completed += (asyncOperation, status) =>
        {
            try
            {
                switch (status)
                {
                    case AsyncStatus.Completed:
                        completionSource.TrySetResult(asyncOperation.GetResults());
                        break;
                    case AsyncStatus.Canceled:
                        completionSource.TrySetCanceled();
                        break;
                    case AsyncStatus.Error:
                        completionSource.TrySetException(asyncOperation.ErrorCode);
                        break;
                }
            }
            catch (Exception ex)
            {
                completionSource.TrySetException(ex);
            }
            finally
            {
                asyncOperation.Close();
            }
        };

        return completionSource.Task;
    }
}

该实现的核心逻辑是通过TaskCompletionSource封装异步操作的状态流转,监听WinRT异步操作的Completed事件,在操作结束后再对应设置Task的完成/取消/异常状态,全程不会阻塞调用线程,同时释放IAsyncOperation资源避免内存泄漏。

内容的提问来源于stack exchange,提问作者Mselmi Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 02:30:05