REST サービスと対話するために、独自の実装を作成しました (非常に簡単です)。GET リクエストのコードは以下にあります。ただし、リクエストのパフォーマンスを低下させる明らかな落とし穴がコードにあるかどうかを知りたいです。彼らは今のところまともに働いていますが、もっと良い仕事ができたのではないかと感じています。
どんなフィードバックでも大歓迎です!
public static void Get<T>(string url, Action<Result<T>> callback, NetworkCredential credentials = null, JsonConverter converter = null)
{
// Checks for no internet
if (!NetworkInterface.GetIsNetworkAvailable())
{
callback(new Result<T>(new NoInternetException()));
return;
}
// Sets up the web request for the given URL (REST-call)
var webRequest = WebRequest.Create(url) as HttpWebRequest;
// Makes sure we'll accept gzip encoded responses
webRequest.Headers[HttpRequestHeader.AcceptEncoding] = "gzip";
// If any credentials were sent, attach them to request
webRequest.Credentials = credentials;
// Queues things up in a thread pool
ThreadPool.QueueUserWorkItem((object ignore) =>
{
// Starts receiving the response
webRequest.BeginGetCompressedResponse(responseResult =>
{
try
{
// Fetches the response
var response = (HttpWebResponse)webRequest.EndGetResponse(responseResult);
// If there _is_ a response, convert the JSON
if (response != null)
{
// Gives us a standard variable to put stuff into
var result = default(T);
// Creates the settings-object to insert all custom converters into
var settings = new JsonSerializerSettings();
// Inserts the relevant converters
if (converter != null)
{
if (converter is JsonMovieConverter)
{
settings.Converters.Add(new JsonMovieListConverter());
}
settings.Converters.Add(converter);
}
// Depending on whether or not something is encoded as GZIP - deserialize from JSON in the correct way
if (response.Headers[HttpRequestHeader.ContentEncoding] == "gzip")
{
var gzipStream = response.GetCompressedResponseStream();
result = JsonConvert.DeserializeObject<T>(new StreamReader(gzipStream).ReadToEnd(), settings);
}
else
{
result = JsonConvert.DeserializeObject<T>(new StreamReader(response.GetResponseStream()).ReadToEnd(), settings);
}
// Close the response
response.Close();
// Launch callback
callback(new Result<T>(result));
}
}
catch (Exception ex) // Deals with errors
{
if (ex is WebException && ((WebException)ex).Response != null && ((HttpWebResponse)((WebException)ex).Response).StatusCode == HttpStatusCode.Unauthorized)
{
callback(new Result<T>(new UnauthorizedException()));
}
else
{
callback(new Result<T>(ex));
}
}
}, webRequest);
});
}
一般に、このコードは一目瞭然ですが、さらにいくつかの事実があります。
- メソッドを提供するDelayの最適化された gzip-decoderを使用しています
GetCompressedResponse()
(基本的には元のメソッドと同じです)。 - JSON を正しく逆シリアル化するために、いくつかの JSON.net カスタム JsonConverter クラスを作成しました。これらはかなり単純で、パフォーマンスには影響しません。
- Result-class は、単に結果のラッパー クラスです (Value フィールドと Error フィールドを含みます)。