1

my environment version is 2.0, I am currently working with Unity 5.5, c#. I am experiencing a stall the 3rd time i try to get an HttpWebRequest request stream.

What I want to achieve is having a mechanism of "retry": when I send a request I wait for the response and if it times out I send another request and refresh the time out. I stop this loop when I hit MAX_ATTEMPTS or one of the requests get a response (even if it is from a request that has timed out).

The code that handles this loop is here:

    IEnumerator DoRequest()
    {
        List<IAsyncResult> results = new List<IAsyncResult>(MAX_ATTEMPTS);
        int attemptNumber = 1;
        while (attemptNumber <= MAX_ATTEMPTS)
        {
            IAsyncResult result = null;
            try
            {
                result = SendRequest();
            }
            catch (Exception e)
            {
                ProcessException(e);
                yield break;
            }

            if (result != null)
            {
                results.Add(result);
                DateTime timeOutTime = DateTime.UtcNow + TIMEOUT;
                yield return null;
                while (DateTime.UtcNow < timeOutTime)
                {
                    int completedIndex = -1;
                    if (IsAnyResultCompleted(results, out completedIndex) == true)
                    {
                        ProcessResponse(results[completedIndex]);
                        yield break;
                    }
                    else
                    {
                        yield return null;
                    }
                }

            }
            attemptNumber++;
        }

        if (results.Count != 0)
        {
            ProcessResponseFail("Timed out");
        }
        else
        {
            ProcessResponseFail("Unable to generate a request");
        }
    }

Where TIMEOUT is a TimeSpan of 10 seconds. And IsAnyResultCompleted is just a for loop that checks if any request has IsCompleted set to true.

Here I create and send the request:

    IAsyncResult SendRequest()
    {

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(RequestActionPath);

        request.ContentType = "application/json";
        request.Accept = "application/json";
        request.Method = "POST";

        string json = JsonUtility.ToJson(_dependency);

        using (StreamWriter sw = new StreamWriter(request.GetRequestStream()))
        {
            sw.Write(json);
            sw.Flush();
        }

        IAsyncResult result = request.BeginGetResponse(new AsyncCallback(onResponse), request);

        return result;
    }

"onResponse" is a cached delegate and it is assigned to this:

    void OnResponse(IAsyncResult asynchronousResult)
    {

        try
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
            request.EndGetResponse(asynchronousResult);

        }
        catch (WebException e)
        {
            string responseStream;
            using (var streamReader = new StreamReader(e.Response.GetResponseStream()))
            {
                responseStream = streamReader.ReadToEnd();
            }

            Utility.Console.LogError(responseStream);
        }
    }

I am well aware of this and I also tried to set ServicePointManager.DefaultConnectionLimit = 1000000 but the result is always the same, after 2 sent requests GetRequestStream() in SendRequest stalls for 5 seconds and I cannot understand why.

Alakanu
  • 325
  • 2
  • 11

0 Answers0