Question

Tous les appels asynchrones à HttpWebRequest.BeginGetResponse / EndGetResponse et à HttpWebResponse.GetResponseStream (). BeginRead / EndRead sont créés à partir de blocs try / catch, mais ces exceptions se propagent et ne laissent aucune chance de les gérer et d’arrêter la résiliation de l’application:

  

Exception non gérée: System.IO.IOException: Impossible de lire les données de la connexion de transport: Une connexion établie a été abandonnée par le logiciel de votre ordinateur hôte. --- > System.Net.Sockets.SocketException: une connexion établie a été abandonnée par le logiciel de votre ordinateur hôte

     

Exception non gérée: System.IO.IOException: Impossible de lire les données de la connexion de transport: Une connexion existante a été fermée de force par l'hôte distant. --- > System.Net.Sockets.SocketException: une connexion existante a été fermée de force par l'hôte distant

Unhandled Exception: System.IO.IOException: Unable to read data from the transport connection: An established connection was aborted by the software in your host machine. ---> System.Net.Sockets.SocketException: An established connection was aborted by the software in your host machine
   at System.Net.Sockets.Socket.BeginReceive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, AsyncCallback callback, Object state)
   at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   at System.Net.PooledStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   at System.Net.ConnectStream.BeginReadWithoutValidation(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   at System.Net.ConnectStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   at System.IO.Compression.DeflateStream.ReadCallback(IAsyncResult baseStreamResult)
   at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
   at System.Net.ContextAwareResult.CompleteCallback(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Net.ContextAwareResult.Complete(IntPtr userToken)
   at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
   at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

Fragments de code réels:

public static RequestState StartDownload(string url, string referer, RequestData data, DownloadEventHandler completedHandler, DownloadExceptionHandler failedHandler)
{
    RequestState state = null;

    try
    {
        var request = CreateWebRequest(url, referer, data);
        state = new RequestState(url, data, request)
        {
            DownloadCompleted = completedHandler;
            DownloadFailed = failedHandler;
        }

        state.ResponseAsyncResult = request.BeginGetResponse(WebResponseCallback, state);
        state.AsyncTimeoutHandle = ThreadPool.RegisterWaitForSingleObject(state.CompletedHandle, DownloadTimeoutCallback, state, TimeSpan.FromSeconds(data.DownloadTimeout), true);
    }
    catch(Exception ex)
    {
        Trace.TraceError(ex.ToString());
    }

    return state;
}

private static void DownloadTimeoutCallback(object state, bool timedOut)
{
    var requestState = (RequestState)state;

    try
    {
        requestState.AsyncTimeoutHandle.Unregister(null);

        if(timedOut)
        {
            requestState.Request.Abort();
        }
    }
    catch(Exception ex)
    {
        Trace.TraceError(ex.ToString());
    }
}

private static void WebResponseCallback(IAsyncResult asyncResult)
{
    var state = (RequestState)asyncResult.AsyncState;
    try
    {
        var response = (HttpWebResponse)state.Request.EndGetResponse(asyncResult);
        WebResponse(state, response);
    }
    catch (Exception ex)
    {
        Trace.TraceError(ex.ToString());
    }
}

private static void WebResponse(RequestState state, HttpWebResponse response)
{
    state.ActualUrl = state.Request.Address.ToString();
    state.Response = response;

    BeginRead(state);
}

private static void BeginRead(RequestState state)
{
    var stream = state.Response.GetResponseStream();
    state.ReadAsyncResult = stream.BeginRead(state.Buffer, 0, state.BufferSize, ReadCallBack, state);
}

private static void ReadCallBack(IAsyncResult asyncResult)
{
    var state = (RequestState)asyncResult.AsyncState;

    try
    {
        var stream = state.Response.GetResponseStream();
        var bytesRead = stream.EndRead(asyncResult);

        if (bytesRead > 0)
        {
            //there is still more data to read
            state.AppendResponseData(state.Buffer, 0, bytesRead);
            BeginRead(state);
        }
        else
        {
            state.Response.Close();
            state.InvokeDownloadCompleted();
        }       
    }
    catch(Exception ex)
    {
        Trace.TraceError(ex.ToString());
    }
}

PS: Un rapport de bogue a été archivé à l'adresse Microsoft Connect https: / /connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=510564

Était-ce utile?

La solution 2

Publié par Microsoft le 16/11/2009 à 11h14

  

Ce problème a été résolu dans le .NET 4.0 Framework.

     

Merci,

     

Équipe de la bibliothèque de classes réseau

https://connect.microsoft.com/VisualStudio/feedback /ViewFeedback.aspx?FeedbackID=510564

Autres conseils

Je pense que la raison en est que l'exception déclenchée sur un thread différent de celui qui a initié BegainGetResponse, ce qui explique l'appel System.Threading.ExecutionContext.Run dans la pile d'appels.  Le cas peut être que vous quittez le bloc catch try avant que l'exception ne soit levée. Ainsi, elle est levée sans aucun gestionnaire. Pouvez-vous s'il vous plaît poster votre partie du code afin que je puisse voir comment nous pouvons l'améliorer

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top