0
私はhttpリクエストを行い、失敗するとリクエストを繰り返します。私はインターネットケーブルをコンピュータに接続して再接続してシミュレーションします。ほとんどの場合、私のコードは動作しますが、時にはco_await HttpClient :: PutAsyncは決して完了しません(C++、コルーチン、UWPを使用)
co_await HttpClient :: PutAsync()は決して "返す"または完了しません。
task<Aws::Result> Aws::S3Request::tryExecute()
{
// content
IHttpContent^ httpContent;
httpContent = ref new HttpBufferContent(mBufferContent);
httpContent->Headers->ContentType = ref new Headers::HttpMediaTypeHeaderValue(ref new String(mContentType.c_str()));
std::wstring signature = getSignature();
// client
auto filter = ref new ::Filters::HttpBaseProtocolFilter;
filter->AllowUI = false;
filter->CacheControl->ReadBehavior = Filters::HttpCacheReadBehavior::NoCache;
filter->CacheControl->WriteBehavior = Filters::HttpCacheWriteBehavior::NoCache;
HttpClient^ httpClient = ref new HttpClient(filter);
httpClient->DefaultRequestHeaders->Authorization = ref new Headers::HttpCredentialsHeaderValue(L"AWS", ref new String((mUser.mAccessKey + L":" + signature).c_str()));
httpClient->DefaultRequestHeaders->Append(L"Date", ref new String(mDate.c_str()));
httpClient->DefaultRequestHeaders->Append(L"x-amz-acl", L"public-read");
httpClient->DefaultRequestHeaders->Append(L"x-amz-security-token", ref new String(mUser.mSessionToken.c_str()));
// http req
Uri^ uri = ref new Uri(ref new String(mUri.c_str()));
HttpResponseMessage^ response;
IAsyncOperationWithProgress<HttpResponseMessage^, HttpProgress>^ progress;
try
{
progress = httpClient->PutAsync(uri, httpContent);
progress->Progress = ref new AsyncOperationProgressHandler<HttpResponseMessage^, HttpProgress>(
[this](IAsyncOperationWithProgress<HttpResponseMessage^, HttpProgress>^ pretask, HttpProgress progressInfo)
{
/*double got = progressInfo.BytesReceived + progressInfo.BytesSent;
double total = 0;
if (progressInfo.TotalBytesToReceive)
total += progressInfo.TotalBytesToReceive->Value;
if (progressInfo.TotalBytesToSend)
total += progressInfo.TotalBytesToSend->Value;
float progress = (total >= 1) ? float(got/total) : 0.0f;
debugOut("--- part progress = ", progress);
if (mProgress)
*mProgress = progress;*/
}
);
response = co_await progress;
progress = nullptr;
if (!response->IsSuccessStatusCode)
debugOut("--- http fail error");
}
catch (Platform::COMException^)
{
debugOut("--- http fail nointernet");
progress = nullptr;
mResult = NoInternet;
mAnswer.clear();
co_return mResult;
}
// answer
mAnswer = response->Content->ToString()->Data();
debugOut(L"--- Http answer=", mAnswer);
mResult = response->IsSuccessStatusCode ? Success : Error;
co_return mResult;
}
それが失敗した場合、tryExecute()が再び呼び出されます。
私のコードは次のようになります。
ところで、IAsyncOperationWithProgressは、私には0%か100%のどちらかしか与えてくれません。私は各要求に5Mバイトのサイズをアップロードします。
ので、これは100%再現問題ではありません「私のコードは動作しますが、時には、ほとんどの時間」?失敗した時代のスペシャルですか?サーバー側でput要求に制約がありましたか? –
おそらくケーブルのプラグを抜いて再接続する時間の10%で、co_waitのPutAsyncは決して「戻る」か完了しません。タイムアウトがありません。 – Morten