0

現在、このコードを使用して、各クライアントにわずかに異なるメッセージを送信しています。100 以上のクライアントがある場合、タスクのないこの同じコードがタイマー ループをブロックしており、すべての Web 要求もブロックしていると思われます。

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 でサポートされていますか?

4

1 に答える 1

0

client.changedI/O バウンドまたは CPU バウンドですか?

I/O バウンドだと思います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ただし、人工的な Task.Run` ではなく、自然な API を使用するようにしてください。

于 2013-09-09T22:43:52.983 に答える