在WinRT应用程序中抛出的webeexception无法被捕获

本文关键字:webeexception 应用程序 WinRT | 更新日期: 2023-09-27 18:07:45

这个问题真的很奇怪,我在调试时都没有尝试过。只有在Surface平板电脑上运行应用程序时才会出现这种情况。在华硕平板电脑上或在Visual Studio中运行时不会出现这种情况。在打开飞行模式的特定场景中,抛出了一个我完全无法捕获的webeexception。我甚至不能完全确定我的代码中是什么导致了这种情况的发生,因为由于未知的原因,我的一些日志记录在代码中的某个点之后没有发生。我只能假设它是由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块中,所以我看不出webeexception是怎么可能通过的。

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,手机或以太网,则不允许代码继续运行,但这并没有捕捉到连接到没有互联网连接的网络的情况。WinRT没有解决方案来检查互联网连接,甚至我使用的方法也不太友好(它只是传递一个数字—http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/d8e76732-19d3-47b3-840f-70d87c75ce9f)。

在WinRT应用程序中抛出的webeexception无法被捕获

您试过处理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;
}

这个问题可能是由于回调中抛出了一个未处理的异常;回调在一个不同于调用初始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);

就像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
}