2010-04-20 3 views
3

Lors de l'écriture de données sur un serveur Web, mes tests montrent HttpWebRequest.ReadWriteTimeout est ignoré, contrairement à MSDN spec. Par exemple, si je mets ReadWriteTimeout à 1 (= 1 msec), appelez myRequestStream.Write() en passant dans un tampon qui prend 10 secondes à transférer, il transfère avec succès et ne expire jamais en utilisant .NET 3.5 SP1. Le même test fonctionnant sur Mono 2.6 fois immédiatement comme prévu. Quel pourrait être le problème?HttpWebRequest ReadWriteTimeout ignoré dans .NET; fonctionne dans Mono

+0

Vos tests avec .NET et mono sont-ils effectués sur le même serveur et sur le même hôte? – feroze

+0

Même serveur, pas le même hôte. – jimvfr

Répondre

4

Il semble y avoir un bug où le timeout d'écriture, lorsqu'il est défini sur l'instance de Stream retournée par BeginGetRequestStream(), n'est pas propagé vers le socket natif. Je vais déposer un bug pour m'assurer que ce problème est corrigé pour une prochaine version du .NET Framework.

Voici une solution de contournement.

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; 
+0

Merci beaucoup! Je vais essayer la solution de contournement. On dirait que le correctif sera compatible même après un bug dans le framework .NET est corrigé? – jimvfr

+0

Testé la solution de contournement; ça fonctionne bien. Pouvez-vous me dire le numéro de bogue de Microsoft à ce sujet? – jimvfr