Попробуйте/поймать, не перехватывая HttpListenerException

Я сделал простую конечную точку http, используя Grapevine (это просто интерфейс для HttpListener). Иногда соединение обрывается раньше, чем я SendResponse, что приводит к HttpListenerException, но я не понимаю, почему try/catch не обрабатывает исключение и весь сервер падает.

Ошибка:

Application: Movimiento de Placas.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Net.HttpListenerException
Stack:
   at System.Net.HttpResponseStream.Write(Byte[], Int32, Int32)
   at Grapevine.Interfaces.Server.HttpResponse.SendResponse(Byte[])
   at Grapevine.Server.HttpResponseExtensions.SendResponse(Grapevine.Interfaces.Server.IHttpResponse, System.String)
   at Grapevine.Server.Router.Route(System.Object)
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

Код:

[RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "/patente")]
        public IHttpContext ModificarPantalla(IHttpContext context)
        {
            var dict = HttpUtility.ParseQueryString(context.Request.Payload);
            var json = new JavaScriptSerializer().Serialize(
                dict.Keys.Cast<string>()
                    .ToDictionary(k => k, k => dict[k]));
            var contenido = JsonConvert.DeserializeObject<Patente>(json);
            Server.FormRef.CargarPatente(contenido.Plate, contenido.idCamera);
            UltimaFoto.Fecha = DateTime.Now;
            Task.Run(() => Sqlite.InsertarPatente(contenido));
            try
            {
                context.Response.SendResponse(HttpStatusCode.Ok); //exception occurs here
            }
            catch (Exception ex)
            {

            }

            return context;
        }

person Vallo    schedule 03.04.2019    source источник
comment
Ваш улов ничего не делает. Что вы собираетесь делать, даже если поймаете исключение?   -  person gilliduck    schedule 03.04.2019
comment
Избегайте сбоя всей программы, в этом суть. Мне не нужно ничего делать, когда соединение обрывается.   -  person Vallo    schedule 03.04.2019
comment
@Vallo Я только что опубликовал 4.1.2, скоро он будет доступен на nuget.org   -  person Scott Offen    schedule 09.08.2019


Ответы (2)


Это известная проблема. Уже некоторое время висит PR, который исправляет это, сейчас я объединяю его вместе с обновлением, которое добавит поддержку .NET Standard. Это должно быть доступно к концу недели.

Обновление: Grapevine 4.1.2 доступен на Nuget.org с 9 августа 2019 г.

person Scott Offen    schedule 17.04.2019

Это могло произойти, если SendResponse был асинхронным и вы его не ждали.

person CRice    schedule 03.04.2019
comment
SendResponse не является асинхронным. namespace Grapevine.Server { public static class HttpResponseExtensions { public static void SendResponse(this IHttpResponse response, HttpStatusCode statusCode); } } - person Vallo; 03.04.2019
comment
Интересно, если это дело где-то глубже в этом методе. Некоторый вызов Task.Run может быть таким же, как в вашем примере. Я не понимаю, как иначе он мог бы избежать этого блока. Может быть, исключение генерируется откуда-то еще, и вы думаете, что это из-за этой попытки? - person CRice; 04.04.2019
comment
почти уверен, что это строка, вызывающая это, поскольку это единственная конечная точка в моей программе. Я должен начать смотреть исходный код Grapevine, чтобы понять, почему исключение не перехватывается. - person Vallo; 04.04.2019