HttpWebRequest ReadWriteTimeout игнорируется в .NET; работает в моно - PullRequest
3 голосов
/ 21 апреля 2010

При записи данных на веб-сервер мои тесты показывают, что HttpWebRequest.ReadWriteTimeout игнорируется, в отличие от спецификации MSDN . Например, если я установил ReadWriteTimeout в 1 (= 1 мсек), вызову myRequestStream.Write (), передающему в буфер, для передачи которого требуется 10 секунд, он выполняется успешно и никогда не прерывается с использованием .NET 3.5 SP1. Тот же тест, запущенный на Mono в 2,6 раза сразу же, как и ожидалось. Что может быть не так?

1 Ответ

4 голосов
/ 01 мая 2010

Кажется, есть ошибка, когда таймаут записи, установленный для экземпляра Stream, возвращенного вам BeginGetRequestStream (), не распространяется вниз на собственный сокет. Я сообщу об ошибке, чтобы убедиться, что эта проблема исправлена ​​в следующем выпуске .NET Framework.

Вот обходной путь.

private static void SetRequestStreamWriteTimeout(Stream requestStream, int timeout)
{
  // Work around a framework bug where the request stream write timeout doesn't make it
  // to the socket. The "m_Chunked" field indicates we are performing chunked reads. Since
  // this stream is being used for writes, the value of this field is irrelevant except
  // that setting it to true causes the Eof property on the ConnectStream object to evaluate
  // to false. The code responsible for setting the socket option short-circuits when it
  // sees Eof is true, and does not set the flag. If Eof is false, the write timeout
  // propagates to the native socket correctly.

  if (!s_requestStreamWriteTimeoutWorkaroundFailed)
  {
    try
    {
      Type connectStreamType = requestStream.GetType();
      FieldInfo fieldInfo = connectStreamType.GetField("m_Chunked", BindingFlags.NonPublic | BindingFlags.Instance);
      fieldInfo.SetValue(requestStream, true);
    }
    catch (Exception)
    {
      s_requestStreamWriteTimeoutWorkaroundFailed = true;
    }
  }

  requestStream.WriteTimeout = timeout;
}

private static bool s_requestStreamWriteTimeoutWorkaroundFailed;
...