C# 为什么不';捕获此异常:现有连接被远程主机强制关闭

C# 为什么不';捕获此异常:现有连接被远程主机强制关闭,c#,exception,windows-phone-8,exception-handling,C#,Exception,Windows Phone 8,Exception Handling,我对从我的Windows Phone 8应用程序中收到的一些错误报告感到有点困惑,因为我觉得我的try-catch块(你在下面的代码中看到的)应该能够捕捉到这个特定问题: private async void ConnectionReceivedCallback(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) { DataReader reader = new DataR

我对从我的Windows Phone 8应用程序中收到的一些错误报告感到有点困惑,因为我觉得我的try-catch块(你在下面的代码中看到的)应该能够捕捉到这个特定问题:

private async void ConnectionReceivedCallback(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
    DataReader reader = new DataReader(args.Socket.InputStream);
    reader.InputStreamOptions = InputStreamOptions.Partial;
    uint numStrBytes = await reader.LoadAsync(512);
    string request = reader.ReadString(numStrBytes);

    using (IOutputStream output = args.Socket.OutputStream)
    {
        string requestMethod = request.Split('\n')[0];
        string[] requestParts = requestMethod.Split(' ');

        if (requestParts[0] == "GET")
        {
            string url = HttpUtility.UrlDecode(requestParts[1].Replace("/?", ""));

            int z = Convert.ToInt32(GetUrlParam(url, "z"));
            int x = Convert.ToInt32(GetUrlParam(url, "x"));
            int y = Convert.ToInt32(GetUrlParam(url, "y"));

            y = GetYForTmsTileSystem(y, z);

            bool foundTileProvider = false;
            if (MapTileHelper.IsMapTileValid(x, y, z))
            {
                foreach (IMapTileProvider tileProvider in _tileProviders)
                {
                    if (tileProvider.CanProvideMapTile(x, y, z))
                    {
                        foundTileProvider = true;
                        try
                        {
                            await tileProvider.SendMapTileResponse(x, y, z, output);
                        }
                        catch
                        {
                            // Just fail nicely if there's an issue
                        }
                        break;
                    }
                }
            }

            if (!foundTileProvider)
            {
                using (Stream resp = output.AsStreamForWrite())
                {
                    byte[] headerArray = Encoding.UTF8.GetBytes(
                        "HTTP/1.1 404 Not Found\r\n" +
                        "Content-Length:0\r\n" +
                        "Connection: close\r\n\r\n");
                    await resp.WriteAsync(headerArray, 0, headerArray.Length);
                }
            }
        }
        else
        {
            throw new InvalidDataException("HTTP method not supported: " + requestParts[0]);
        }
    }
}
我看到错误报告如下:

System.Exception: An existing connection was forcibly closed by the remote host.

An existing connection was forcibly closed by the remote host.

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at TopoMap.Map.MapTileServer.d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.b__4(Object state)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
如果相关,则在try-catch块内执行的代码:

public async Task SendMapTileResponse(int x, int y, int zoomLevel, IOutputStream response)
{
    string url = MapTileHelper.BuildMapTileUrl(x, y, zoomLevel);
    if (string.IsNullOrEmpty(url)) return;

    using (HttpClient client = new HttpClient())
    {
        Stream imageStream = null;

        HttpResponseMessage mapTileResponse = await client.GetAsync(url, HttpCompletionOption.ResponseContentRead);
        if (mapTileResponse.IsSuccessStatusCode)
        {
            imageStream = await mapTileResponse.Content.ReadAsStreamAsync();
        }

        if (imageStream != null)
        {
            using (Stream resp = response.AsStreamForWrite())
            {
                MapTileProviderHelper.WriteImageHeaderToResponseStream(resp, imageStream.Length);

                // Cache map tile
                if (UserData.CacheMap)
                {
                    // NOTE: BinaryWriter inside this method will close the imageStream once it's done, so we need to reload the image!
                    //       Also tried imageStream.CopyToAsync(resp) before saving image, but this doesn't work well either.
                    SaveImage(MapTileHelper.GetMapTileCacheFilePath(x, y, zoomLevel), imageStream);

                    using (IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        using (IsolatedStorageFileStream fs = isolatedStorage.OpenFile(MapTileHelper.GetMapTileCacheFilePath(x, y, zoomLevel), FileMode.Open, FileAccess.Read))
                        {
                            await fs.CopyToAsync(resp);
                        }
                    }
                }
                else
                {
                    await imageStream.CopyToAsync(resp);
                }

                await resp.FlushAsync();
            }
        }
    }
}

知道我为什么会看到这些异常吗?

异常被抛出到执行异步方法的线程中,因此异常不会传播到主线程。您应该在方法中处理异常,并通过返回的任务变量中包含的信息通知主线程。

您确定堆栈是从try-catch内部提交的,而不是ConnectionReceivedCallback中的其他代码,如LoadAsync?什么调用实际引发异常?你用调试器检查过了吗?当您的调用堆栈突然返回到其调用方法时,您将知道抛出了一个异常。@Jeroenvanevel-不幸的是,我无法在开发中复制此异常。这是从野外收到的一些错误报告中得出的。@Linky-我不是100%确定,但我想你可能是对的。好像我戴着眼罩!我还将尝试将LoadAsync代码包装在try-catch块中,并等待查看问题是否仍然得到报告。感谢潜在的修复。我直接在SendMapTilerResponse中捕获异常,但是如果一个异常是由子异步函数调用引发的,那么我确实无法捕获该异常。谢谢你的回答-非常感谢。