如何在SignalR客户端中使用async/await与hub.On

Gre*_*ter 8 .net c# async-await signalr.client

我有一个与SignalR Hub(服务器)通信的.Net Windows服务(客户端).大多数客户端方法需要时间才能完成.当从服务器接收调用时,我如何(或者我需要)包装目标方法/ hub.On以避免警告:

"因为没有等待这个调用,所以当前方法的执行在调用完成之前继续.考虑将await运算符应用于调用的结果"

在客户端上,这是启动/设置代码的示例:

IHubProxy _hub
string hubUrl = @"http://localhost/";

var connection = new HubConnection(hubUrl, hubParams);
_hub = connection.CreateHubProxy("MyHub");
await connection.Start();

_hub.On<Message>("SendMessageToClient", i => OnMessageFromServer(i.Id, i.Message));
_hub.On<Command>("SendCommandToClient", i => OnCommandFromServer(i.Id, i.Command));
Run Code Online (Sandbox Code Playgroud)

同样在客户端上,这是方法的示例:

public static async Task<bool> OnMessageFromServer(string Id, string message)
{
    try
    {
        var result = await processMessage(message);  //long running task
    }
    catch (Exception ex)
    {
        throw new Exception("There was an error processing the message: ", ex);
    }
    return result;
}

public static async Task<bool> OnCommandFromServer(string Id, string command)
{
    try
    {
        var result = await processCommand(command);  //long running task
    }
    catch (Exception ex)
    {
        throw new Exception("There was an error processing the message: ", ex);
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

最终,我认为_hub.On正在注册回调,而不是来自服务器的实际执行(调用).我想我需要进入实际执行的中间,等待On [X] FromServer的结果并返回结果.

*************更新后的示例和更正后的代码*********************

IHubProxy _hub
string hubUrl = @"http://localhost/";

var connection = new HubConnection(hubUrl, hubParams);
_hub = connection.CreateHubProxy("MyHub");
await connection.Start();

//original
//_hub.On<Message>("SendMessageToClient", i => OnMessageFromServer(i.Id, i.Message));
//_hub.On<Command>("SendCommandToClient", i => OnCommandFromServer(i.Id, i.Command));

//new async 
_hub.On<Message>("SendMessageToClient", 
    async (i) => await OnMessageFromServer(i.Id, i.Message));

_hub.On<Message>("SendCommandToClient", 
    async (i) => await OnCommandFromServer(i.Id, i.Message));

//expanding to multiple parameters
_hub.On<Message, List<Message>, bool, int>("SendComplexParamsToClient", 
    async (p1, p2, p3, p4) => 
       await OnComplexParamsFromServer(p1.Id, p1.Message, p2, p3, p4));    
Run Code Online (Sandbox Code Playgroud)

然后目标方法签名就像

public static async Task<bool> OnComplexParamsFromServer(string id, string message,
                 List<Message> incommingMessages, bool eatMessages, int repeat)
{
    try
    {
        var result = await processCommand(message);  //long running task
        if (result) 
        {
             // eat up your incoming parameters
        }
    }
    catch (Exception ex)
    {
        throw new Exception("There was an error processing the message: ", ex);
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

感谢@AgentFire的快速反应!!!

Age*_*ire 7

这是一个无法等待的模式,使用它像这样:

_hub.On<Message>("SendMessageToClient", async i => await OnMessageFromServer(i.Id, i.Message))
Run Code Online (Sandbox Code Playgroud)

  • 您的答案是互联网上唯一一个*void-awaitable*的资源.我也不明白*async void*与此有什么关系,另外*async void*非常不鼓励. (4认同)
  • 是的,async-void方法对每个人来说都是众所周知的.有三种类型的异步方法和......你应该了解整个事情,实际上.不会伤害你的:] (2认同)