コード例 #1
0
    // Tasks and message are passed by ref so they can be lazily created inside the method post-filtering,
    // while still being re-usable when sending to multiple groups
    private static void SendToGroupConnections(string methodName, object?[] args, ConcurrentDictionary <string, HubConnectionContext> connections, Func <HubConnectionContext, object?, bool>?include, object?state, ref List <Task>?tasks, ref SerializedHubMessage?message, CancellationToken cancellationToken)
    {
        // foreach over ConcurrentDictionary avoids allocating an enumerator
        foreach (var connection in connections)
        {
            if (include != null && !include(connection.Value, state))
            {
                continue;
            }

            if (message == null)
            {
                message = DefaultHubLifetimeManager <THub> .CreateSerializedInvocationMessage(methodName, args);
            }

            var task = connection.Value.WriteAsync(message, cancellationToken);

            if (!task.IsCompletedSuccessfully)
            {
                if (tasks == null)
                {
                    tasks = new List <Task>();
                }

                tasks.Add(task.AsTask());
            }
            else
            {
                // If it's a IValueTaskSource backed ValueTask,
                // inform it its result has been read so it can reset
                task.GetAwaiter().GetResult();
            }
        }
    }
コード例 #2
0
    private Task SendToAllConnections(string methodName, object?[] args, Func <HubConnectionContext, object?, bool>?include, object?state = null, CancellationToken cancellationToken = default)
    {
        List <Task>?         tasks   = null;
        SerializedHubMessage?message = null;

        // foreach over HubConnectionStore avoids allocating an enumerator
        foreach (var connection in _connections)
        {
            if (include != null && !include(connection, state))
            {
                continue;
            }

            if (message == null)
            {
                message = DefaultHubLifetimeManager <THub> .CreateSerializedInvocationMessage(methodName, args);
            }

            var task = connection.WriteAsync(message, cancellationToken);

            if (!task.IsCompletedSuccessfully)
            {
                if (tasks == null)
                {
                    tasks = new List <Task>();
                }

                tasks.Add(task.AsTask());
            }
            else
            {
                // If it's a IValueTaskSource backed ValueTask,
                // inform it its result has been read so it can reset
                task.GetAwaiter().GetResult();
            }
        }

        if (tasks == null)
        {
            return(Task.CompletedTask);
        }

        // Some connections are slow
        return(Task.WhenAll(tasks));
    }