大量 (100k+) の JSON ファイルをできるだけ早くヒットし、それらをシリアル化し、要求の HTTP 応答ステータス コード (成功したか失敗したかに関係なく) を保存したいと考えています。(私は と を使用System.Runtime.Serialization.Json
していますDataContract
)。ステータス コードとシリアル化されたオブジェクトをさらに処理するつもりですが、テスト ベッドとして次のコード スニペットを用意しました。
List<int> ids = new List<int>();
for (int i = MIN; i < MAX; i++)
ids.Add(i);
var tasks = ids.Select(id =>
{
var request = WebRequest.Create(GetURL(id));
return Task
.Factory
.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, id)
.ContinueWith(t =>
{
HttpStatusCode code = HttpStatusCode.OK;
Item item = null;
try
{
using (var stream = t.Result.GetResponseStream())
{
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Item));
item = ((Item)jsonSerializer.ReadObject(stream));
}
}
catch (AggregateException ex)
{
if (ex.InnerException is WebException)
code = ((HttpWebResponse)((WebException)ex.InnerException).Response).StatusCode;
}
});
}).ToArray();
Task.WaitAll(tasks);
このアプローチを使用することで、以前行っていた同期アプローチよりもはるかに高速にファイルを処理することができました。
ただし、ステータス コードがまたはGetResponseStream()
の場合に がスローされることはわかっています。したがって、これらのステータス コードをキャプチャするには、この例外をキャッチする必要があります。ただし、この TPL のコンテキストでは、on にネストされています。これにより、この行は非常に混乱します。WebException
4xx
5xx
InnerException
AggregateException
code = ((HttpWebResponse)((WebException)ex.InnerException).Response).StatusCode;
ただし、これは機能します...このコンテキストでそのような例外をキャプチャするためのより良い/より明確な方法があるかどうか疑問に思っていましたか?