private Task DispatchSocket(ISocket socket)
    {
        if (socket is null)
        {
            return(Completed);
        }

        var socketQueueIdentifier = socket.GetEndPointString();

        Queue <QueueItem> queue;

        lock (SocketQueues)
        {
            if (!SocketQueues.TryGetValue(socketQueueIdentifier, out queue))
            {
                // No queue created yet. Nothing to dispatch.
                return(Completed);
            }
        }

        if (queue.Count == 0)
        {
            return(Completed);
        }

        // Check if socket is ready for new packages.
        int queueSize = socket.GetSendQueueSize();

        if (queueSize > MaxQueueSizeForDispatch)
        {
#if DEBUG
            Log.LogTrace("Package queue size: " + queueSize);
#endif
            return(Completed);
        }

        // Send package
        QueueItem item;
        lock (queue)
        {
            item = queue.Dequeue();
        }

        try
        {
            item.ZRpc.Invoke(item.Target, new object[] { item.Package });

            Log.LogTrace($"Sending package with size '{item.Package.Size()}' to '{item.Target}'");
        }
        catch (Exception e)
        {
            if (item.Retries > 3)
            {
                Log.LogWarning($"Error while trying to send package. Too many retries, will stop trying.", e);
            }
            else
            {
                lock (queue)
                {
                    // Requeue package
                    item.Retries++;
                    queue.Enqueue(item);
                }
            }
        }

        return(Completed);
    }