簡體   English   中英

SignalR Hub 中應該使用異步還是非異步方法?

[英]Should async or non-async methods be used in SignalR Hub?

我在SignalR部分有以下Hub類,在這里我定義了與連接相關的所有方法:

public override Task OnConnected()
{
    // here I cannot call this, and need to convert this method async
     await AddToGroup("stockGroup");
    //

    string name = Context.User.Identity.Name;
    _connections.Add(name, Context.ConnectionId);
    return base.OnConnected();
}

public async Task AddToGroup(string groupName)
{
    await Groups.Add(Context.ConnectionId, groupName);
    await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} joined");
}

我查看了許多關於這些連接方法(和其他 Hub 方法)的不同示例,發現其中一些使用async方法,而另一些則不使用。 在上面的示例中,我需要將OnConnected()方法轉換為async以便調用AddToGroup()方法。 當然相反的情況也可以,但我不確定哪個更好。 那么,我應該對Hub中的所有方法使用async方法還是非異步方法? 任何幫助,將不勝感激。

更新 1:轉換的方法(到異步)。

public override async Task OnConnected()
{        
    await AddToGroup("stockGroup");

    string name = Context.User.Identity.Name;
    _connections.Add(name, Context.ConnectionId);
    return base.OnConnected();
}

更新 2:

public override async Task OnConnected()
{
    // #1 There is no async method in "Microsoft.AspNet.SignalR" library. 
    //await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");  

    // #2 I just have sync version of "AddToGroupAsync()" and used it
    await Groups.Add(Context.ConnectionId, "SignalR Users");

    /* #3 I think there is no need to use this custom method in the Hub. 
    Because the same method is already exist in the IGroupManager interface */
    //await AddToGroup("jiraGroup");        
    
    string name = Context.User.Identity.Name;
    _connections.Add(name, Context.ConnectionId);

    // #4 Here also the same problem and I used sync version of OnConnected()
    //await base.OnConnectedAsync();
    await base.OnConnected();
}

如果您需要await內部方法,只需添加async async是編譯器生成異步狀態機的標志。

should I use async - 如果您需要等待,請使用。

如果您不需要await ,只需返回任務本身而不使用async 在這種情況下,您可以避免創建狀態機。

另請閱讀 Stephen Toub 的Async/Await 常見問題解答

當您使用“async”關鍵字標記方法時,您實際上是在告訴編譯器兩件事:

  1. 您告訴編譯器您希望能夠在方法中使用“await”關鍵字(當且僅當它所在的方法或 lambda 標記為異步時,您才能使用 await 關鍵字)。 這樣做時,您是在告訴編譯器使用狀態機編譯該方法,以便該方法能夠掛起,然后在等待點異步恢復。

  2. 您是在告訴編譯器“提升”方法的結果或返回類型中可能出現的任何異常。 對於返回 Task 或 Task 的方法,這意味着在方法中未處理的任何返回值或異常都將存儲到結果任務中。 對於返回 void 的方法,這意味着任何異常都會通過方法初始調用時當前的任何“SynchronizationContext”傳播到調用者的上下文。

您應該將Async方法與await一起使用並return Task

異步是病毒式的,所以你應該避免async void

壞的:

public async void MethodAsync()
{
    var result = await SendAsync();
    DoSomething(result);
}
    

好的:

public async Task MethodAsync()
{
    var result = await SendAsync();
    DoSomething(result);
}

@davidfowl 這里有一些很棒的異步指南。

更新:刪除return

public override async Task OnConnected()
{        
    await AddToGroup("stockGroup");

    string name = Context.User.Identity.Name;
    _connections.Add(name, Context.ConnectionId);
    await base.OnConnected();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM