Domanda

Tutte le chiamate asincrone a HttpWebRequest.BeginGetResponse / EndGetResponse e HttpWebResponse.GetResponseStream (). BeginRead / EndRead sono fatte da blocchi try / catch, tuttavia, queste eccezioni si propagano e non lasciano una possibilità gestirle e arrestare la chiusura dell'applicazione:

  

Eccezione non gestita: System.IO.IOException: impossibile leggere i dati dalla connessione di trasporto: Una connessione stabilita è stata interrotta dal software nel computer host. --- > System.Net.Sockets.SocketException: una connessione stabilita è stata interrotta dal software nel computer host

     

Eccezione non gestita: System.IO.IOException: impossibile leggere i dati dalla connessione di trasporto: Una connessione esistente è stata forzatamente chiusa dall'host remoto. --- > System.Net.Sockets.SocketException: una connessione esistente è stata forzatamente chiusa dall'host remoto

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)

Frammenti di codice effettivi:

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: una segnalazione di bug è stata depositata su Microsoft Connect https: / /connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=510564

È stato utile?

Soluzione 2

Inserito da Microsoft il 16/11/2009 alle 11:14

  

Questo problema è stato risolto in .NET 4.0 Framework.

     

Grazie

     

Team della libreria di classi di rete

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

Altri suggerimenti

Penso che il motivo sia che l'eccezione è stata sollevata su un thread diverso da quello che ha avviato BegainGetResponse, e questo spiega la chiamata System.Threading.ExecutionContext.Run nello stack di chiamate.  Il caso potrebbe essere che esci dal blocco try catch prima che venga sollevata l'eccezione, quindi si solleva senza alcun gestore, puoi per favore pubblicare la tua parte del codice in modo che io possa vedere come possiamo migliorarlo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top