void Scenario7::Start_Click()

in archived/HttpClient/cpp/Scenario7_PostStreamWithProgress.xaml.cpp [78:192]


void Scenario7::Start_Click(Object^ sender, RoutedEventArgs^ e)
{
    Helpers::ScenarioStarted(StartButton, CancelButton, nullptr);
    ResetFields();
    rootPage->NotifyUser("In progress", NotifyType::StatusMessage);

    Uri^ resourceAddress;

    // The value of 'AddressField' is set by the user and is therefore untrusted input. If we can't create a
    // valid, absolute URI, we'll notify the user about the incorrect input.
    if (!rootPage->TryGetUri(AddressField->Text, &resourceAddress))
    {
        rootPage->NotifyUser("Invalid URI.", NotifyType::ErrorMessage);
        return;
    }

    const unsigned long long streamLength = 100000;
    HttpStreamContent^ streamContent = ref new HttpStreamContent(ref new SlowInputStream(streamLength));

    // If stream length is unknown, the request is chunked transfer encoded.
    if (!ChunkedRequestToggle->IsOn)
    {
        streamContent->Headers->ContentLength = streamLength;
    }

    // Do an asynchronous POST.
    IAsyncOperationWithProgress<HttpRequestResult^, HttpProgress>^ operation = httpClient->TryPostAsync(resourceAddress, streamContent);
    operation->Progress = ref new AsyncOperationProgressHandler<HttpRequestResult^, HttpProgress>([=](
        IAsyncOperationWithProgress<HttpRequestResult^, HttpProgress>^ asyncInfo,
        HttpProgress progress)
    {
        rootPage->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([=]()
        {
            StageField->Text = progress.Stage.ToString();
            RetriesField->Text = progress.Retries.ToString();
            BytesSentField->Text = progress.BytesSent.ToString();
            BytesReceivedField->Text = progress.BytesReceived.ToString();

            unsigned long long totalBytesToSend = 0;
            if (progress.TotalBytesToSend != nullptr)
            {
                totalBytesToSend = progress.TotalBytesToSend->Value;
                TotalBytesToSendField->Text = totalBytesToSend.ToString();
            }
            else
            {
                TotalBytesToSendField->Text = "unknown";
            }

            unsigned long long totalBytesToReceive = 0;
            if (progress.TotalBytesToReceive != nullptr)
            {
                totalBytesToReceive = progress.TotalBytesToReceive->Value;
                TotalBytesToReceiveField->Text = totalBytesToReceive.ToString();
            }
            else
            {
                TotalBytesToReceiveField->Text = "unknown";
            }

            unsigned long long requestProgress = 0;
            if (progress.Stage == HttpProgressStage::SendingContent && totalBytesToSend > 0)
            {
                requestProgress = progress.BytesSent * 50 / totalBytesToSend;
            }
            else if (progress.Stage == HttpProgressStage::ReceivingContent)
            {
                // Start with 50 percent, request content was already sent.
                requestProgress += 50;

                if (totalBytesToReceive > 0)
                {
                    requestProgress += progress.BytesReceived * 50 / totalBytesToReceive;
                }
            }
            else
            {
                return;
            }

            RequestProgressBar->Value = static_cast<double>(requestProgress);
        }));
    });

    // Continue when the POST completes.
    create_task(operation, cancellationTokenSource.get_token())
        .then([this](HttpRequestResult^ result)
    {
        if (result->Succeeded)
        {
            rootPage->NotifyUser("Completed", NotifyType::StatusMessage);
        }
        else
        {
            Helpers::DisplayWebError(rootPage, result->ExtendedError);
        }
    }).then([=](task<void> previousTask)
    {
        // This sample uses a "try" in order to support cancellation.
        // If you don't need to support cancellation, then the "try" is not needed.
        try
        {
            // Check if the task was canceled.
            previousTask.get();

        }
        catch (const task_canceled&)
        {
            rootPage->NotifyUser("Request canceled.", NotifyType::ErrorMessage);
        }

        RequestProgressBar->Value = 100;
        Helpers::ScenarioCompleted(StartButton, CancelButton);
    });
}