Отмена в запросах WebApi - PullRequest
       20

Отмена в запросах WebApi

0 голосов
/ 08 февраля 2019

Существует несколько ресурсов об отмене запросов WebApi с помощью CancellationTokens, например (похоже, концепция применима ко всем последним версиям):

Теперь я также узнал, что обычно для HTTP-соединения вы не открываете и не закрываете TCP-соединение каждый раз, когда отправляете новый запрос, но часто оставляете TCP-соединение открытым, по крайней мере, так я понялэта статья из MDN: Типичная HTTP-сессия .

Поэтому мой вопрос:

Если я выполняю HTTP-запросы из C #, будет ли создано базовое TCP-соединениеи каждый раз закрывается, так что механизм по сути TCP-соединение закрывается и сервер может запросить отмену в токене?

Так ли это в конце ретрансляции на тот факт, что я всегда открываю новый TCPсоединение для каждого запроса?Или есть что-то еще позади (также), которое также будет работать в сценарии, где TCP-соединение не будет закрыто?

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Вам не нужно беспокоиться о том, закрыто ли соединение или нет после обмена запросом-ответом HTTP, потому что это не влияет на механизм отмены.Что определенно влияет на то, что соединение закрывается во время обмена HTTP-запросом-ответом, так как это вызывает отмену обработки запроса на стороне сервера в случае, если он обрабатывает токены отмены.Другими словами, если соединение закрывается до отправки ответа, независимо от того, какой тип соединения (сохраняется или для обмена), это является причиной для сервера инициировать процесс отмены.

0 голосов
/ 08 февраля 2019

Вот исходный код метода HttpWebrequest.Abort () из Github.

     private void Abort(Exception exception, int abortState)
    {
        GlobalLog.ThreadContract(ThreadKinds.Unknown, "HttpWebRequest#" + ValidationHelper.HashString(this) + "::Abort()");
        if (Logging.On) Logging.Enter(Logging.Web, this, "Abort", (exception == null? "" :  exception.Message));

        if(Interlocked.CompareExchange(ref m_Aborted, abortState, 0) == 0) // public abort will never drain streams
        {
            GlobalLog.Print("HttpWebRequest#" + ValidationHelper.HashString(this) + "::Abort() - " + exception);

            NetworkingPerfCounters.Instance.Increment(NetworkingPerfCounterName.HttpWebRequestAborted);

            m_OnceFailed = true;
            CancelTimer();

            WebException webException = exception as WebException;
            if (exception == null)
            {
                webException = new WebException(NetRes.GetWebStatusString("net_requestaborted", WebExceptionStatus.RequestCanceled), WebExceptionStatus.RequestCanceled);
            }
            else if (webException == null)
            {
                webException = new WebException(NetRes.GetWebStatusString("net_requestaborted", WebExceptionStatus.RequestCanceled), exception, WebExceptionStatus.RequestCanceled, _HttpResponse);
            }

            try
            {

                    // Want to make sure that other threads see that we're aborted before they set an abort delegate, or that we see
                    // the delegate if they might have missed that we're aborted.
                    Thread.MemoryBarrier();
                    HttpAbortDelegate abortDelegate = _AbortDelegate;

                    if (abortDelegate == null || abortDelegate(this, webException))
                    {
                        // We don't have a connection associated with this request

                        SetResponse(webException);
                    }
                    else
                    {
                        // In case we don't call SetResponse(), make sure to complete the lazy async result
                        // objects. abortDelegate() may not end up in a code path that would complete these
                        // objects.
                        LazyAsyncResult writeAResult = null;
                        LazyAsyncResult readAResult = null;

                        if (!Async)
                        {
                            lock (this)
                            {
                                writeAResult = _WriteAResult;
                                readAResult = _ReadAResult;
                            }
                        }

                        if (writeAResult != null)
                            writeAResult.InvokeCallback(webException);

                        if (readAResult != null)
                            readAResult.InvokeCallback(webException);
                    }

                    if (!Async)
                    {
                        LazyAsyncResult chkConnectionAsyncResult = ConnectionAsyncResult;
                        LazyAsyncResult chkReaderAsyncResult = ConnectionReaderAsyncResult;

                        if (chkConnectionAsyncResult != null)
                            chkConnectionAsyncResult.InvokeCallback(webException);
                        if (chkReaderAsyncResult != null)
                            chkReaderAsyncResult.InvokeCallback(webException);
                    }

                    if (this.IsWebSocketRequest && this.ServicePoint != null)
                    {
                        this.ServicePoint.CloseConnectionGroup(this.ConnectionGroupName);
                    }

            }
            catch (InternalException)
            {
            }
        }

        if(Logging.On)Logging.Exit(Logging.Web, this, "Abort", "");
    }

Это ясно показывает, что соединения TCP закрываются.Сервер по-своему реагирует на закрытый порт TCP.ссылка: https://serverfault.com/questions/147886/what-happens-when-a-http-request-is-terminated-prematurely

...