RestRequestAsyncHandle.Abort () не будет вызывать CancellationToken.IsCancellationRequested - PullRequest
0 голосов
/ 26 июня 2019

У меня одновременно работают два приложения на C #.Одним из них является консольное приложение C #, которое отправляет вызовы REST другому, а другое работает на собственном сервере отдыха Нэнси.

Вот действительно базовое представление некоторых кодов обеих частей.

RestsharpClient:

public async void PostAsyncWhile()
{
    IRestClient RestsharpClient = new RestClient("http://localhost:50001");

    var request = new RestRequest($"/nancyserver/whileasync", Method.POST);

    var asyncHandle = RestsharpClient.ExecuteAsync(request, response =>
    {
        Console.WriteLine(response.Content.ToString());
    });

    await Task.Delay(1000);

    asyncHandle.Abort();//PROBLEM
}

NancyRestServer:

public class RestModule : NancyModule
{
    public RestModule() : base("/nancyserver")
    {
        Post("/whileasync", async (args, ctx) => await WhileAsync(args, ctx));
    }

    private async Task<bool> WhileAsync(dynamic args, CancellationToken ctx)
    {
        do
        {
            await Task.Delay(100);
            if (ctx.IsCancellationRequested)//PROBLEM
            {
                break;
            }
        }
        while (true);

        return true;
    }
}

Клиент отправляет команду на запуск цикла while на сервере, ожидает 1 с и прерывает асинхронный вызов.

Проблема, с которой я столкнулся, заключается в том, что asyncHandle.Abort();, по-видимому, не вызывает ctx.IsCancellationRequested на стороне сервера.

Как мне отменить / прервать асинхронный вызов прихост-сервер nancy, использующий клиент restsharp?

1 Ответ

1 голос
/ 26 июня 2019

Есть пара частей, которые касаются отмены веб-запроса.

Во-первых, клиент должен поддерживать отмену и использовать эту отмену, чтобы закрыть соединение. Поэтому первое, что нужно сделать, это отслеживать сетевые пакеты (например, используя Wireshark) и убедиться, что RestSharp отправляет RST (сброс), а не просто закрывает свою сторону соединения. RST - это сигнал другой стороне, что вы хотите отменить запрос. Закрытие соединения - это сигнал другой стороне, что вы закончили отправку данных, но все еще готовы получить ответ.

Далее сервер должен поддерживать обнаружение отмены. Не все серверы делают. Долгое время ASP.NET (pre-Core) не должным образом поддерживал отмену запроса по инициативе клиента. Было какое-то состояние гонки, при котором оно не отменялось должным образом (не помню деталей), поэтому они отключили этот путь отмены. Все это было решено в ASP.NET Core, но AFAIK, это никогда не было исправлено в ASP.NET Legacy Edition.

Если RestSharp не отправляет RST, откройте проблему с этой командой. Если Нэнси не отвечает на RST, откройте проблему с этой командой. Если это проблема ASP.NET, команда Nancy должна знать это (и отвечать, сообщая вам, что не может это исправить), и в этом случае вам не повезло. : /

...