【问题标题】:WebException thrown in WinRT app that cannot be caught无法捕获的 WinRT 应用程序中引发的 WebException
【发布时间】:2013-04-05 16:29:22
【问题描述】:

这个问题真的很奇怪,我在调试时没有尝试过。仅在 Surface 平板电脑上运行应用程序时才会发生。它不会出现在华硕平板电脑上或在 Visual Studio 中运行时。在飞行模式已打开的特定场景中,会引发我绝对无法捕捉到的 WebException。我什至不完全确定我的代码中是什么导致了它的发生,因为由于未知原因,我的某些日志记录在代码中的某个点之后没有发生。我只能假设它是由 HttpWebRequest 引起的,因为抛出的异常类型似乎来自内部 .NET 组件。这是我能够获得的唯一调试信息。它来自 Windows 事件查看器:

Application: <myappname.exe>
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Net.WebException
Stack:
    at System.Net.ServicePoint.ConnectSocketCallback(System.IAsyncResult)
    at System.Net.LazyAsyncResult.Complete(IntPtr)
    at System.Net.ContextAwareResult.Complete(IntPtr)
    at System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object, IntPtr)
    at System.Net.Sockets.Socket.ConnectCallback()
    at System.Net.Sockets.Socket.RegisteredWaitCallback(System.Object, Boolean)
    at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(System.Object, Boolean)

我真的希望我能提供更多的调试信息,但我已经尝试了所有我能想到的一切,到处都有大量的 try/catch 块并在大多数调用后记录——其中一些没有被执行。有没有人知道是什么原因造成的?

编辑 1:

根据跟踪,异常似乎是在这里的某个地方抛出的。几乎所有东西都包裹在一个 try/catch 块中,所以我看不出 WebException 是如何漏掉的。

byte[] bytes = Encoding.UTF8.GetBytes(requestXml.ToString());
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.ContentType = "text/xml";

try
{
    IAsyncResult requestResult = (IAsyncResult)request.BeginGetRequestStream((rAsyncResult) =>
    {
        using (Stream uploadStream = request.EndGetRequestStream(rAsyncResult))
        {
            try
            {
                uploadStream.Write(bytes, 0, bytes.Length);
                uploadStream.Flush();
            }
            catch (Exception e)
            {
                // Exception handling
            }
            finally
            {
                uploadStream.Dispose();
            }
        }

        IAsyncResult responseResult = (IAsyncResult)request.BeginGetResponse((resAsyncResult) =>
        {
            try
            {
                using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(resAsyncResult))
                {
                    try
                    {
                        data = ProcessResponse(XmlReader.Create(response.GetResponseStream()));
                    }
                    catch (Exception e)
                    {
                        // Exception handling
                    }
                    finally
                    {
                        response.Dispose();
                    }
                }
            }
            catch (WebException e)
            {
                // Exception handling
            }

        }, null);
    }, null);
}
catch (Exception e)
{
    // Exception handling
}

编辑 2:

我仍然没有找到可接受的解决方案。我目前正在事先检查连接类型,如果代码未连接到 WiFi、移动或以太网,则不允许代码继续运行,但这并没有捕捉到它连接到没有 Internet 连接的网络的情况。 WinRT 没有检查互联网连接的解决方案,甚至我使用的方法也不友好(它只是传回一个数字--http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/d8e76732-19d3-47b3-840f-70d87c75ce9f)。

【问题讨论】:

  • 也许显示你的代码会有所帮助..,如果有异常,有办法捕捉它..也许你试图错误地捕捉它..
  • @DJ KRAZE 我认为抛出异常的代码已发布。
  • 这真的是你的Exception Code Block 的样子吗..?你没有处理任何异常
  • @DJ KRAZE 不,我在发布之前修剪了代码以消除不相关的错误消息记录和业务逻辑。

标签: c# windows-runtime system.net.webexception winrt-async


【解决方案1】:

您是否尝试处理Application.UnhandledException

App类构造函数中添加事件处理函数:

public App()
{
    // keep the rest of the constructor
    this.UnhandledException += OnUnhandledException;
}

在事件处理程序中,您可以记录异常并处理标记以防止应用关闭/崩溃:

void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    // log e.Exception details for investigation
    e.Handled = true;
}

【讨论】:

【解决方案2】:

问题可能是由于您的回调中抛出了未处理的异常;回调在与调用初始 request.BeginGetRequestStream 的线程不同的线程中异步执行的可能性很高,这就是为什么您没有在外部 try/catch 块中捕获它的原因。 您应该能够通过将回调的全部内容包装在 try/catch 块中来解决这个问题,即:

IAsyncResult requestResult = (IAsyncResult)request.BeginGetRequestStream((rAsyncResult) =>
{
    try
    {
        using (Stream uploadStream = request.EndGetRequestStream(rAsyncResult))
        {
            try
            {
                uploadStream.Write(bytes, 0, bytes.Length);
                uploadStream.Flush();
            }
            catch (Exception e)
            {
                // Exception handling
            }
            finally
            {
                uploadStream.Dispose();
            }
        }

        IAsyncResult responseResult = (IAsyncResult)request.BeginGetResponse((resAsyncResult) =>
        {
            try
            {
                using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(resAsyncResult))
                {
                    try
                    {
                        data = ProcessResponse(XmlReader.Create(response.GetResponseStream()));
                    }
                    catch (Exception e)
                    {
                        // Exception handling
                    }
                    finally
                    {
                        response.Dispose();
                    }
                }
            }
            catch (WebException e)
            {
                // Exception handling
            }

        }, null);
    }
    catch (Exception ex)
    {
        // Handle the exception as you wish
    }
}, null);

【讨论】:

    【解决方案3】:

    就像 Efran Cobisi 所说的 EndGetRequestStream 可能是抛出异常的函数。即使有异常, using 语句也会释放对象,因此不需要 try finally 来释放它。 但无论如何,您应该使用异步方法,这将使代码更具可读性并且更容易捕获异常。相当于您的代码将是:

    byte[] bytes = Encoding.UTF8.GetBytes(requestXml.ToString());
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
    request.Method = "POST";
    request.ContentType = "text/xml";
    
    try
    {
    
        using (Stream uploadStream = await request.GetRequestStreamAsync())
        {
            await uploadStream.WriteAsync(bytes, 0, bytes.Length);
            await uploadStream.FlushAsync();
        }
    
        using (HttpWebResponse response = (HttpWebResponse) await request.GetRequestStreamAsync())
        {
            data = ProcessResponse(XmlReader.Create(response.GetResponseStream()));
        }
    
    }
    catch (Exception e)
    {
        // Exception
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-22
      • 1970-01-01
      • 2010-12-23
      • 1970-01-01
      • 2013-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多