简体   繁体   中英

server to client message using async in signalr

currently i'm using this code to send to each client a slightly different message. When there are 100+ clients, this same code without task is blocking my timer loop, and i suspect it to also block all web requests.

ConcurrentDictionary Sessions;
// ...


var context = GlobalHost.ConnectionManager.GetHubContext<TiHub>();
foreach(var kp in Sessions) 
{
    var client = context.Clients.Client(kp.Key);
    if (client != null)
     {
          client.changed(new Data{ data=somevalue(kp.Value) });
     }
}

Async version

        var context = GlobalHost.ConnectionManager.GetHubContext<TiHub>();

        return Task.Run(() =>
        {
            Parallel.ForEach(Sessions, kp =>
            {
                var client = context.Clients.Client(kp.Key);
                if (client != null)
                {
                    client.changed(new Data{ data=somevalue(kp.Value) });
                }
            });

        });

I would like a task or async version of "changed". Something like:

client.changedAsync(new Data{ data=somevalue(kp.Value) });

Is this supported in SignalR ?

Is client.changed I/O bound or CPU bound?

I suppose it's I/O bound and you'll benefit from async-await .

Instead of the Parallel.ForEach you might try something like this:

var context = GlobalHost.ConnectionManager.GetHubContext<TiHub>();
var tasks = (from kp in Sessions
             let client = context.Clients.Client(kp.Key)
             where client != null
             select Task.Run(() =>
                 {
                     client.changed(new Data{ data = somevaluekp.Value);
                 })).ToArray();

await Task.WhenAll(tasks);

But you should try to use natural async-await APIs instead of the artificial Task.Run`.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM