Asp.net core signalr 信令核心-按顺序处理的请求

Asp.net core signalr 信令核心-按顺序处理的请求,asp.net-core-signalr,Asp.net Core Signalr,若我通过一个连接向一个集线器发出多个请求,那个么服务器将按顺序执行这些请求。因此,平行主义没有进步 我的中心有三种不同的方法 public Task Test1(string invokeId) { Clients.Caller.SendAsync("Hello", $"Test1: Before Delay ... InvokeID: {invokeId}"); Task.Delay(5000).Wait(); Clients.C

若我通过一个连接向一个集线器发出多个请求,那个么服务器将按顺序执行这些请求。因此,平行主义没有进步

我的中心有三种不同的方法

    public Task Test1(string invokeId)
    {
        Clients.Caller.SendAsync("Hello", $"Test1: Before Delay ... InvokeID: {invokeId}");
        Task.Delay(5000).Wait();
        Clients.Caller.SendAsync("Hello", $"Test1: After Delay ...  InvokeID: {invokeId}");
        return Task.CompletedTask;
    }

    public Task Test2(string invokeId)
    {
        Clients.Caller.SendAsync("Hello", $"Test2: Before Delay ... InvokeID: {invokeId}");
        Task.Delay(2500).Wait();
        Clients.Caller.SendAsync("Hello", $"Test2: After Delay ...  InvokeID: {invokeId}");
        return Task.CompletedTask;
    }

    public Task Test3(string invokeId)
    {
        Clients.Caller.SendAsync("Hello", $"Test3: Before Delay ... InvokeID: {invokeId}");
        Task.Delay(1250).Wait();
        Clients.Caller.SendAsync("Hello", $"Test3: After Delay ...  InvokeID: {invokeId}");
        return Task.CompletedTask;
    }
我在循环中从客户端.NET应用程序调用它们

_connection.SendAsync("Test1", "1").ContinueWith(t => Console.WriteLine($"Test1: { t.Status }"));
_connection.SendAsync("Test2", "2").ContinueWith(t => Console.WriteLine($"Test2: { t.Status }"));
_connection.SendAsync("Test3", "3").ContinueWith(t => Console.WriteLine($"Test3: { t.Status }"));
跟随法

_connection.On("Hello", new Type[] { typeof(string) }, (parameters, state) =>
{
    return Console.WriteLine((string)parameters[0]);
}, _connection);
我得到以下输出

  • 测试1:随机完成
  • 测试2:随机完成
  • 测试3:随机完成
  • 测试1:在延迟之前。。。第1部分:1
  • 测试1:延迟之后。。。第1部分:1
  • 测试2:在延迟之前。。。第二节:2
  • 测试2:延迟之后。。。第二节:2
  • 测试3:在延迟之前。。。第二节:3
  • 测试3:延迟之后。。。第二节:3
如果您看到“Test2:Before Delay…InvokeID:2”将在“Test1:after Delay…InvokeID:1”之后直接调用。看起来,同一时间只允许一个中心对象,不管如何,所有三个调用都将立即返回“RanToCompletion”,它们将一个接一个地执行

这看起来非常具体,但我想构建一个应用程序,其中每个图形WPF对象都将调用SignalR来检索内容。如果按顺序调用它们,我必须寻找另一种解决方案


我错过了什么?

您还没有指定,但如果我不得不猜测,我会说您正在本地测试,这可能意味着您也在使用IIS Express。IIS Express是单线程的,因此多个并发请求将始终排队,因为需要一个线程来处理每个请求

至于为什么您的
RanToCompletion
日志排在第一位,您还没有提供任何实际记录这些日志的代码。结果,我又不得不在黑暗中冒险了。很可能在记录该消息之前,您没有正确地等待异步任务。然后,任务本身将在完成时运行并完成,但调用代码会继续运行并在这之前点击
RanToCompletion
日志行

编辑


实际上,我现在明白了
RanToCompletion
的作用。它必须是
t.Status
的值。异步方法中的代码会立即返回,因为您不会在其中等待任何内容。包含的异步任务已启动,但在方法返回时尚未完成。然后,您的
ContinueWith
lambda将运行,之后内部的任务将完成并记录其他消息。

消息将由SignalR Core内的设计按顺序处理

我查了资料来源。课堂评论

Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher
作用

public override Task DispatchMessageAsync(HubConnectionContext connection, HubMessage hubMessage)
        // Messages are dispatched sequentially and will stop other messages from being processed until they complete.
        // Streaming methods will run sequentially until they start streaming, then they will fire-and-forget allowing other messages to run.

因此,您必须创建额外的类来处理您的操作,并且您的中心必须立即返回。但是不要忘记将connectionId传递给您的班级,这样您就可以使用connectionId进行回复,因为您原来的中心同时被破坏了。

谢谢您,克里斯。是的,RANTO完成来自t状态。但这是我所期望的行为。在客户端,我希望发送“请求”并继续(示例GUI)。但在服务器上,请求将依次处理。如您所见,Test3只等待Test1的1/4。但在调试期间,您会看到Test1之后的Test2之后调用Test3。感谢您对IIS Express的提示。今天我将在一个单独的服务器上与IIS进行检查。你知道我必须检查的特殊设置吗?不知道。这只是单线程和多线程的简单问题。在完整的IIS上应该可以正常工作。Chris,它将按顺序处理。我在SignalR Core的一篇评论中发现了这一点。您是否知道如何在请求中写入此内容并将其标记为已解决?我是编辑原始请求还是添加新的答案?这很简单,不要阻塞hub方法,一切都会好起来。对于阅读的任何人来说,如果是这样的话,可能已经不是这样了。在
Microsoft.AspNetCore.signar.Internal.DefaultHubDispatcher
中再也找不到提到的注释。我在文档中也找不到与此相关的任何具体内容。Iirc,MS指出,我们不应该依赖于执行顺序——在实际用例中使用顺序执行的想法之前,自己检查并尝试。