如何使用IAsyncOperation接口在WinRT中进行自己的异步操作?

7

我正在开发一款地铁应用,并且想要创建一些异步操作,让我的类来实现。

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


为什么不试着根据(相当稀少的)文档实现方法呢? - svick
显然,你对所涉及的内容并没有深入的了解。这就是文档所建议的。即便如此,还是要感谢你。 - Claudio Junior
2
我不明白。文档建议在SO上询问? - svick
6个回答

4

在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的一个好建议。 - Filip Skakun
对不起,问题中没有指定语言。 - maxim pg


2

是的,可以看看Ben Kuhn在//BUILD/大会上的演讲:http://channel9.msdn.com/events/BUILD/BUILD2011/PLAT-203T。他展示了如何构建异步API。

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

这里有关于AsyncBase类的文档。


据我所知,他展示了如何使用.Net类“AsyncInfoFactory”构建异步接口,而这在C++/CX中是不可用的。 - svick
1
PPL是长期解决方案,显然现在不是一个选择。但异步API相对简单。请查看wrl\async.h,WRL::AsyncBase类允许您创建一个异步C++类。请注意,它仅适用于低级C++类,而不是高级类,因此在开发者预览版本上可能会遇到一些挑战。 - Larry Osterman
谢谢大家。虽然期望微软提供一些解决方案和模式更为合理,但事实上,我仍在参考这些材料,但正如你所看到的,它们并没有鼓励我走任何道路。 - Claudio Junior

2
我在微软论坛上发布了同样的问题,他们给了我两个回复。第一个是:
“嗨Claudio,
在开发者预览版中,没有一种简单的方法来创建自己的异步操作。我们意识到这个缺点,并正在尝试为下一个公共版本解决它。与此同时,您可以将API设计为异步,并且我们将提供有关如何将同步转换为异步的指导。
谢谢
Visual C ++的Raman Sharma”
当我询问如何用更困难的方式做到这一点时,另一个负责PPL的人告诉我:
“我们计划对我们几周前发布的示例包进行更新,并添加一些关于创建异步操作的示例。我预计将在几周左右完成。如果您关注我们的博客http://blogs.msdn.com/b/nativeconcurrency,您将第一个知道。
至于有多难...我们正在考虑的通用解决方案大约有1000行C ++代码,大量使用模板元编程。其中大部分将在头文件中,因此您可以自行探索。虽然较少的通用解决方案可能不太复杂,但仍需要实现基类、进行状态管理、错误处理等。此时我无法进一步详细说明,但我会说您会喜欢使用PPL编写异步操作的简便性-所以坚持下去!
PPL团队的Artur Laksberg”
那时候没有解决方案。谢谢大家。

0

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


0

虽然有点混乱,但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*>>(...);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接