为什么我没有捕捉到这个异常:远程主机强制关闭了一个现有的连接

本文关键字:连接 一个 主机 异常 为什么 程主机 | 更新日期: 2023-09-27 18:10:34

我对我从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]);
        }
    }
}

我看到的bug报告如下:

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

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

为什么我没有捕捉到这个异常:远程主机强制关闭了一个现有的连接

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