C++/CX:异步方法

The Windows Runtime provides asynchronous APIs and programming patterns that enable your app to continue working while another operation executes on another thread. In addition to this functionality, you can use the exclusive features in the C++ compiler and the Parallel Programming Library (PPL) to write more compact and intuitive asynchronous code.

 Windows Runtime提供了异步API和编程模式来确保当另外的线程上执行另外的操作时,你的应用程序能继续工作。除了这个功能之外,你还能使用C++编译器中独有的特点和PPL写出更紧凑,更只管的异步代码。

The Windows Runtime programming pattern

The Windows Runtime provides asynchronous operations that either return no result; or complete and return a result; or pause periodically to report progress and return results up to that point, and then continue to execute until the operation is complete. The Windows Runtime uses the IAsyncAction, IAsyncOperation, IAsyncActionWithProgress, and IAsyncOperationWithProgress interfaces to manage asynchronous operations. However, the Windows Runtime asynchronous operations are lengthy to write and difficult to read.

Windows Runtime提供异步操作,要么无结果返回,或成功并且有结果,或者暂停定期汇报工作进度,并且返回结果到这一点,并且继续执行直到操作完成。Windows Runtime 使用IAsyncAction, IAsyncOperation, IAsyncActionWithProgress, and IAsyncOperationWithProgress接口来管理异步操作。然而,windows Runtime异步操作代码难写,难读。

We recommend that you use the /ZW compiler option and the tasks feature of the PPL to write compact, intuitive asynchronous code for creating and consuming components.

我们推荐使用/ZW编译选项和PPL的task特征去编写紧凑,直观的代码来创建和使用组件。

You can use the tasks feature to declare a variable of type task<T> that supports a continuation, which is chain of one or more then()functions, and an optional culminating wait() function. The task<T> variable specifies a starting asynchronous method, and the first then()function specifies an event handler, which typically is a lambda function. If the return type of the event handler is another task<void> ortask<TResult> object, you can specify a dot delimiter after the event handler and then a subsequent then() function. In this way, you cancompose a chain of asynchronous actions or operations.

你可以使用tasks特征去声明一个task<T>的变量来支持由一个或多个then()方法,一个可选的最终wait()方法的续集(翻译可能不准)。task<T>指定一个启动异步方法,第一个then()指定一个事件处理程序,通常是lambda函数。如果时间处理程序的返回类型是另外一个task<void>或者task<TResult>对象,你可以在时间处理程序后面指定一个圆点然后是一系列的then()函数。通过这种方法,你可以组成一个异步操作或者操作链。

In addition, you can cancel a continuation or an entire task. For more information, see Parallel Programming with Microsoft Visual C++ andAsynchronous patterns in the Windows Runtime.

此外,你可以取消续集或者整个task。具体信息请参考Parallel Programming with Microsoft Visual C++ andAsynchronous patterns in the Windows Runtime.

Examples

The following "FileAccessSample" sample from the Windows SDK demonstrates the standard Windows Runtime asynchronous programming pattern. The example writes text to a file in your Documents folder.

接下来的 SDK中的"FileAccessSample"例子展示了一个标准的windows Runtime异步编程模式。这个例子写入text到你的文档文件夹中的文件中。

void main()
{
    HANDLE sigEvent = CreateEvent(NULL, FALSE, FALSE, NULL );

    StorageFolder^ item = KnownFolders::DocumentsLibrary;
    StorageFileRetrievalOperation^ createStorageFileOp = item->CreateFileAsync("myFile.txt");

    createStorageFileOp->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>(
        [sigEvent](IAsyncOperation<StorageFile^>^ asyncOp) 
        {
            StreamRetrievalOperation^ streamRetrievalOp = asyncOp->GetResults()->OpenAsync(FileAccessMode::ReadWrite);

            streamRetrievalOp->Completed = ref new AsyncOperationCompletedHandler<IRandomAccessStream^>(
                [sigEvent](IAsyncOperation<IRandomAccessStream^>^ asyncOp2) 
                {
                    IOutputStream^ stream = asyncOp2->GetResults()->GetOutputStreamAt(0);
                    DataWriter^ bbrw = ref new DataWriter(stream);

                    bbrw->WriteString("Hello async!");
                    DataWriterStoreOperation^ writeBinaryStringOp = bbrw->StoreAsync();

                    writeBinaryStringOp->Completed = ref new AsyncOperationCompletedHandler<UINT>(
                    [sigEvent,stream](IAsyncOperation<UINT>^ asyncOp3) 
                    {
                        int bytes = asyncOp3->GetResults();
                        IAsyncOperation<bool>^ streamFlushOp = stream->FlushAsync();
 
                        streamFlushOp->Completed = ref new AsyncOperationCompletedHandler<bool>(
                        [sigEvent](IAsyncOperation<bool>^ asyncOp4) 
                        {
                            bool result = asyncOp4->GetResults();
                            SetEvent(sigEvent);
                        });
                        streamFlushOp->Start();
                    });
                    writeBinaryStringOp->Start();
                });
            streamRetrievalOp->Start();
        });
    createStorageFileOp->Start();

    DWORD dummy;
    CoWaitForMultipleHandles(COWAIT_INPUTAVAILABLE, INFINITE, 1, &sigEvent, &dummy);
    CloseHandle(sigEvent);
}

在下一个例子中使用的PPL任务功能来执行相同的功能,更简单

#include <ppltasks.h>
using namespace concurrency;

void main()
{
    StorageFolder^ item = Windows::Storage::KnownFolders::DocumentsLibrary;
    auto createStorageFileOp = item->CreateFileAsync("myFile.txt");
    task<StorageFile^> t(createStorageFileOp);

    IOutputStream^ ostream = nullptr;

    t.then([](StorageFile^ storageFile) {
        return storageFile->OpenAsync(FileAccessMode::ReadWrite);
    }).then([&](IRandomAccessStream^ rastream) -> IAsyncOperation<UINT>^ {
        ostream = rastream->GetOutputStreamAt(0);
        DataWriter^ bbrw = ref new DataWriter(ostream);
        bbrw->WriteString("Hello async!");
        return bbrw->StoreAsync();
    }).then([&](UINT bytesWritten) {
        return ostream->FlushAsync();
    }).then([](bool flushed) {
    }).wait();
}

附加资源:

 

 

 

posted @ 2012-06-17 16:17  狼哥2  阅读(1785)  评论(0编辑  收藏  举报