قم بإلقاء القبض على JackException غير المعالج أثناء قراءة HttpWebResponse غير المتزامنة

StackOverflow https://stackoverflow.com/questions/1626499

سؤال

جميع الاستدعاءات غير المتزامنة إلى HttpWebRequest.BeginGetResponse/EndGetResponse وHttpWebResponse.GetResponseStream().BeginRead/EndRead مصنوعة من كتل المحاولة/التقاط، ومع ذلك، تنتشر هذه الاستثناءات ولا تترك فرصة للتعامل معها وإيقاف إنهاء التطبيق:

استثناء غير معالج:System.IO.IOException:غير قادر على قراءة البيانات من اتصال النقل: تم إحباط الاتصال القائم بواسطة البرنامج الموجود في جهازك المضيف. ---> System.Net.Sockets.SocketException:تم إحباط الاتصال القائم بواسطة البرنامج الموجود في جهازك المضيف

استثناء غير معالج:System.IO.IOException:غير قادر على قراءة البيانات من اتصال النقل: تم إغلاق اتصال موجود بالقوة بواسطة المضيف البعيد. ---> System.Net.Sockets.SocketException:تم إغلاق اتصال موجود بالقوة بواسطة المضيف البعيد

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)

أجزاء التعليمات البرمجية الفعلية:

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());
    }
}

ملاحظة:تم تقديم تقرير خطأ في Microsoft Connect https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=510564

هل كانت مفيدة؟

المحلول 2

تم النشر بواسطة Microsoft بتاريخ 16/11/2009 الساعة 11:14 صباحًا

تم حل هذه المشكلة في .NET 4.0 Framework.

شكرًا لك،

فريق مكتبة فئة الشبكة

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

نصائح أخرى

أعتقد أن السبب هو أن الاستثناء الذي تم طرحه في موضوع مختلف عن الذي بدأ BegainGetResponse، وهذا ما يفسر System.Threading.ExecutionContext.Run استدعاء في مكدس الاستدعاءات.قد تكون الحالة هي أنك خرجت من كتلة محاولة الالتقاط قبل ظهور الاستثناء، لذلك يتم رفعه بدون معالج له، هل يمكنك من فضلك نشر الجزء الخاص بك من الكود حتى أتمكن من رؤية كيف يمكننا تحسينه

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top