【问题标题】:How Can I make async operations of my own with WinRT using IAsyncOperation interface?如何使用 IAsyncOperation 接口使用 WinRT 进行自己的异步操作?
【发布时间】:2011-12-09 13:39:57
【问题描述】:

我正在开发一个 Metro 应用程序,我想创建一些我自己的类将实现的异步操作。

我只找到了使用 WinRT 操作的异步示例(例如 CreateFileAsync)。我没有发现有人创建异步方法并使用它的任何实例。

【问题讨论】:

  • 你为什么不尝试根据(相当稀缺的)文档来实现这些方法?
  • 显然,您对所涉及的内容没有深入的了解。这就是文档的建议。即使如此,谢谢。
  • 我不明白。文档建议在 SO?

标签: asynchronous windows-8 windows-runtime microsoft-metro c++-cx


【解决方案1】:
【解决方案2】:

在 C++ 中使用create_async

IAsyncOperationWithProgress<IBuffer^, unsigned int>^ RandomAccessStream::ReadAsync(IBuffer^ buffer, unsigned int count, InputStreamOptions options)
{
    if (buffer == nullptr)
        throw ref new InvalidArgumentException;

    auto taskProvider = [=](progress_reporter<unsigned int> progress, cancellation_token token)
    {
        return ReadBytesAsync(buffer, count, token, progress, options);
    };
    return create_async(taskProvider);
}

在 .NET 中使用 AsyncInfo.Run

public IAsyncOperation<IInfo> Async()
{
    return AsyncInfo.Run(_ =>
        Task.Run<AType>(async () =>
        {
            return await DoAsync();
        })
    );
}

【讨论】:

  • 现在 C++/CX 中有一个 await 关键字?还有TPL? :) 但这对于 .NET 来说仍然是一个很好的提示
  • 对不起。问题中未指定语言。
【解决方案3】:

我在微软论坛上发布了同样的问题,他们给了我两个回复。第一个是:

克劳迪奥,

在开发者预览版中,没有一种简单的方法可以创建您自己的 异步操作。我们意识到了这个缺点并正在努力 为下一次公开发布解决它。同时,你可以 将您的 API 设计为异步的,我们将提供有关如何使用的指导 将同步转换为异步。

谢谢

拉曼夏尔马,Visual C++

当我问很难做到这一点时,另一个负责 PPL 的人对我说:

我们计划对我们发布的几个示例包进行更新 几周前并添加了一些有关创建异步操作的示例。一世 预计它会在几周左右发生。如果你保持一个 关注我们的博客http://blogs.msdn.com/b/nativeconcurrency,您将 成为第一个知道的人。

至于它有多难......我们的通用解决方案 正在考虑大约 1000 行 C++ 代码,大量使用 模板元编程。大部分都在头文件中,所以你 可以自己探索。虽然不太通用的解决方案可能会更少 复杂,你仍然需要实现一个基类,做状态 管理,错误处理等。目前我无法深入 细节,但我会说你会喜欢创作是多么容易 使用 PPL 进行异步操作 - 坚持下去!

Artur Laksberg PPL 团队

那么,当时没有解决办法。谢谢大家。

【讨论】:

    【解决方案4】:

    是的,请参阅 Ben Kuhn 的 //BUILD/ 演讲:http://channel9.msdn.com/events/BUILD/BUILD2011/PLAT-203T 他展示了如何构建异步 API。

    目前,对于高级(C++/WX)类没有​​好的解决方案。但是,如果您使用低级 C++ 接口,则可以使用 WRL::AsyncBase 类来帮助构建您的异步接口。

    Here 是关于 AsyncBase 类的文档。

    【讨论】:

    • AFAICS,他展示了如何使用 .Net 类 AsyncInfoFactory 构建异步接口,这在 C++/CX 中不可用。
    • PPL 是长期的解决方案,显然现在不是一个选项。但是异步 API 相对简单。查看 wrl\async.h,WRL::AsyncBase 类允许您创建异步 C++ 类。请注意,它仅适用于低级 C++ 类,而不适用于高级类,因此在开发人员预览版本中使用它可能会遇到一些挑战。
    • 谢谢大家。尽管期望 MS 有一些解决方案和模式,但这似乎更合理。即便如此,我还是会重复使用此材料,但正如您所见,它们并没有鼓励我走任何道路。
    【解决方案5】:

    这很令人困惑,但是 WinRT C++ 代码和 WRL 之间是有区别的。您可以使用 WRL 直接对 ABI 层进行编码。 WRL 不使用异常,但喜欢模板。 WinRT 的推荐编码风格与 WRL 不同。

    我不确定是否每个人都可以做到这一点,但是使用 WRL 你通常需要实现一个继承的类:

    class CreateAysncOp: public RuntimeClass<IAsyncOperation<result_runtime_class*>,AsyncBase<IAsyncCompletedHandler<result_runtime_class*>>
    {
    ...
    

    然后就可以使用了

    hr = MakeAndInitialize<CreateAsyncOp, IAsyncOperation<type_foo*>>(...);
    

    【讨论】:

      【解决方案6】:

      C++ WinRT 现在是实现 WinRT 异步方法的最佳方式。这使用了co_awaitco_return,新的 C++ 语言特性(在标准化过程中)。阅读this page 上的文档。

      【讨论】:

        猜你喜欢
        • 2010-10-02
        • 2017-09-09
        • 2016-12-20
        • 2020-10-01
        • 2018-01-20
        • 1970-01-01
        • 1970-01-01
        • 2016-02-09
        • 1970-01-01
        相关资源
        最近更新 更多