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);
});
}