Search code examples
c++asynchronousrefactoringtaskppl

How to refactor code that is using PPL heavily. C++


So I have function that looks like this

task<shared_ptr<myObjectsResult>> task1 = create_task([this,token, stream]
{
    // Here I have code that is working, but I would like to refactor it
    // maybe even make it go after or before this surrounding task.

    create_task(BitmapDecoder::CreateAsync(stream)).then([this, token]
    (BitmapDecoder^ bitmapDecoder)
    {
        create_task(bitmapDecoder->GetSoftwareBitmapAsync()).then([this, token]
        (SoftwareBitmap^ softwareBitmap)
        {
            OcrEngine^ ocrEngine = OcrEngine::TryCreateFromUserProfileLanguages();
            if (ocrEngine != nullptr)
            {
                create_task(ocrEngine->RecognizeAsync(softwareBitmap)).then([fileInfo, this, transactionPriority, token]
                (OcrResult^ ocrResult)
                {
                    doSomethingWithText(OcrResult->Text->Data());
                });
            }
        });
     });
    ...
    return runAsyncFunctionThatReturnsMyObjectResultTask(token);
});

It works and all is great, but I want to move OCR logic to some other part of code not in here, but I would love to call it from here. What I have tried is creating

task<OcrResult^> GetOCRTextFromStream(_In_ IRandomAccessStream^ stream)
{
    create_task(BitmapDecoder::CreateAsync(stream)).then([]
    (BitmapDecoder^ bitmapDecoder)
    {
         create_task(bitmapDecoder->GetSoftwareBitmapAsync()).then([]
         (SoftwareBitmap^ softwareBitmap)
         {
             OcrEngine^ ocrEngine = OcrEngine::TryCreateFromUserProfileLanguages();
         if (ocrEngine != nullptr)
         {
              return create_task(ocrEngine->RecognizeAsync(softwareBitmap));
         }
         else
         {
               OcrResult^ ocrResult = nullptr;
               return concurrency::task_from_result(ocrResult);
         }
     }
}

and then call this.

GetOCRTextFromStream(stream).then([this, token]
(OcrResult^ ocrResult)
{
    doSomethingWithText(OcrResult->Text->Data());
}

Ofcourse this does not work, but you get what I want, I just want to refactor this, and I just cannot understand how to do what I want, and if it is doable (I guess it is?)

Thanks all and sorry if my question is nooby :)


Solution

  • This is C++/CX, and solution is to put return.

    This should work if you just add return in front of two create_task that you have

    return create_task([]
    {
        return create_task([]
        {
        ...
        }
    }