RestRequestAsyncHandle.Abort()不会触发CancellationToken.IsCancellationRequested

时间:2019-06-26 13:32:02

标签: c# asynchronous restsharp nancy

我有两个同时运行的C#应用​​程序。一个是C#控制台应用程序,它向另一个发送REST调用,另一个正在运行Nancy自托管的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

我应该如何使用restsharp客户端取消/中止nancy主机服务器上的异步呼叫?

1 个答案:

答案 0 :(得分:1)

取消Web请求有两个部分。

首先,客户端必须支持取消并使用该取消来钳制关闭的连接。因此,要做的第一件事是监视网络数据包(例如,使用Wireshark),并确保RestSharp发送RST(重置),并且只是关闭其连接侧。 RST是向另一侧发出您要取消请求的信号。断开连接是向另一侧发出信号,表明您已完成数据发送,但仍然愿意接收响应。

接下来,服务器必须支持检测取消。并非所有服务器都可以。相当长一段时间以来,ASP.NET(预核心)都正确地支持客户端发起的请求取消。在某些比赛条件下,它无法正确取消(不记得详细信息),因此他们禁用了该取消路径。所有这些都已在ASP.NET Core中解决,但是AFAIK在ASP.NET旧版中从未修复过。

如果RestSharp没有发送RST,请向该团队提出问题。如果Nancy没有响应RST,请向该团队提出问题。如果是ASP.NET问题,Nancy团队应该知道(并通知您他们无法修复),在这种情况下,您很不走运。 :/