сообщение сервера для клиента с использованием асинхронного режима в signalr

в настоящее время я использую этот код для отправки каждому клиенту немного другого сообщения. Когда есть более 100 клиентов, этот же код без задачи блокирует мой цикл таймера, и я подозреваю, что он также блокирует все веб-запросы.

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) });
     }
}

Асинхронная версия

        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) });
                }
            });

        });

Я хотел бы, чтобы задача или асинхронная версия «изменились». Что-то типа:

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

Поддерживается ли это в SignalR?


person Softlion    schedule 09.09.2013    source источник


Ответы (1)


Привязан ли client.changed ввод-вывод или процессор?

Я полагаю, что это связано с вводом-выводом, и вы выиграете от async-await.

Вместо Parallel.ForEach вы можете попробовать что-то вроде этого:

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);

Но вы должны попытаться использовать естественные async-await API вместо искусственного Task.Run`.

person Paulo Morgado    schedule 09.09.2013
comment
Концентратор SignalR, по-видимому, не предоставляет методы на основе задач. то есть: было бы неплохо иметь client.changedAsync. Я не хочу блокирующего звонка здесь, поэтому я не буду ждать. Таким образом, причина создания потока с использованием Task.Run. Знакомы ли вы с сигнальщиком? - person Softlion; 10.09.2013
comment
Я знаю, что такое SignalR, но никогда им не пользовался. Я не понимаю вашего комментария. Я не хочу здесь блокирующего звонка, поэтому я не буду ждать. Таким образом, причина создания потока с использованием Task.Run.. - person Paulo Morgado; 10.09.2013
comment
ну тогда вы не знаете signalr, и поэтому вы задаете этот вопрос :) - person Softlion; 10.09.2013