Время ожидания HttpWebRequest.GetRequestStream()

У меня есть служба, которая создает HttpWebRequest и устанавливает его тело со строкой JSON для отправки в системный API. В момент вызова потока запросов я иногда получаю ошибку тайм-аута WebException. Почему это ошибка в этот момент? Проверяет ли он подключение к другой системе, прежде чем продолжить?

try
{
    //Get default request data
    if (requestObj == null)
        requestObj = new ApiRequest();

    //Convert request info to json+bytes
    string url = _baseUrl + path;
    string requestStr = JsonConvert.SerializeObject(requestObj, _jsonSettings);
    requestObjJson = requestStr;

    byte[] data = Encoding.UTF8.GetBytes(requestStr);

    //Post to SystemX
    webRequest = (HttpWebRequest)WebRequest.Create(url);
    webRequest.ContentType = "application/json;charset=UTF-8";
    webRequest.Headers.Add("access_token", _accessToken);
    webRequest.Method = "POST";
    webRequest.ContentLength = data.Length;

    webRequestJson = JsonConvert.SerializeObject(webRequest, Formatting.Indented);

    using (Stream dataStream = webRequest.GetRequestStream())
    {
        dataStream.Write(data, 0, data.Length);
        dataStream.Close();
    }

    webRequestJson = JsonConvert.SerializeObject(webRequest, Formatting.Indented);

    LogMessage("SystemXApiAdapter._request() Request", "Information only. Not an error.", webRequestJson + ";" + requestObjJson, connectionString, customerName, licenseInfoID);

    //Get response
    string responseString = null;
    HttpStatusCode status;
    using (HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse())
    {
        if (response != null)
        {
            using (Stream stream = response.GetResponseStream())
            using (StreamReader sr = new StreamReader(stream))
            {
                responseString = sr.ReadToEnd();
                status = response.StatusCode;
            }

            response.Close();
        }
        else
        {
            status = HttpStatusCode.NoContent;
        }
    }
    T responseObj = null;

    LogMessage("SystemXApiAdapter._request() Response", "Information only. Not an error.", responseString, connectionString, customerName, licenseInfoID);

    if (typeof(T) == typeof(EmptyApiResponse))
        return null;

    if (string.IsNullOrEmpty(responseString))
        throw new Exception("Empty response for non-empty request");

    responseObj = JsonConvert.DeserializeObject<T>(responseString);

    if (callback != null)
        callback(responseObj);

    //Get next page of data if needed
    if (handlePaging && status == HttpStatusCode.PartialContent)
    {
        //Move to next page and recursively make more requests until we've got everything
        requestObj.page_num++;
        T moreData = _request<T>(path, connectionString, customerName, licenseInfoID, true, requestObj, callback);
        if (moreData != null)
            responseObj = (T)(responseObj).AppendResponseData(moreData);
    }

    return responseObj;
}
catch (Exception ex)
{
    SystemXApiException SystemXEx = new SystemXApiException(requestObj, ex, webRequestJson);

    if (!bIsRetry && SystemXEx.StatusCode.HasValue && retryOnStatuses.Contains(SystemXEx.StatusCode.Value))
    {
        return _request<T>(path, connectionString, customerName, licenseInfoID, handlePaging, requestObj, callback, true);
    }
    else
    { 
        throw SystemXEx;
    }

    if (ex is WebException)
    {
        WebException webEx = (WebException)ex;
        HttpStatusCode? StatusCode = null;
        string responseBody = null;

        //Read Status Code
        if (webEx.Status == WebExceptionStatus.ProtocolError)
        {
            var response = webEx.Response as HttpWebResponse;
            if (response != null)
            {
                StatusCode = response.StatusCode;
            }
        }

        //Retry once on applicable status code
        if (!bIsRetry && StatusCode.HasValue && retryOnStatuses.Contains(StatusCode.Value))
            return _request<T>(path, connectionString, customerName, licenseInfoID, handlePaging, requestObj, callback, true);

        //Read response Body
        if (webEx.Response != null)
        {
            using (Stream responseStream = webEx.Response.GetResponseStream())
            using (StreamReader sr = new StreamReader(responseStream, Encoding.Default))
            {
                responseBody = sr.ReadToEnd();
            }
        }
        else
        {
            responseBody = "Empty response body.";
        }

        string message = null;

        //Format new Exception
        if (StatusCode.HasValue)
            message = string.Format("{0} {1}: {2}: {3}: {4}", (int)StatusCode, StatusCode.ToString(), responseBody, requestObjJson, webRequestJson);
        else
            message = string.Format("{0} {1}: {2}: {3}: {4}", "No status code", "No status code", responseBody, requestObjJson, webRequestJson);

        throw new Exception(message, ex);
    }
    else
        throw;
}
finally
{
    if (webRequest != null)
    {
        webRequest.Abort();
    }
}

person James Anderbard    schedule 19.04.2017    source источник


Ответы (1)


Один из вариантов — увеличить срок.

https://msdn.microsoft.com/pt-br/library/system.net.httpwebrequest.timeout(v=vs.110).aspx

webRequest.Timeout=2000; (2 seconds)

Другой - повторить выполнение после тайм-аута, ожидая x секунд.

Любое соединение может столкнуться с проблемами, ваш код должен быть к этому готов.

Я надеюсь, что это помогло в чем-то.

person Akaize    schedule 19.04.2017