public static Task SendFrameAsync(
            this NetMQSocket socket,
            byte[] data,
            bool more = false,
            CancellationToken cancellationToken = default(CancellationToken)
            )
        {
            if (NetMQRuntime.Current == null)
            {
                throw new InvalidOperationException("NetMQRuntime must be created before calling async functions");
            }

            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            socket.AttachToRuntime();

            if (socket.TrySendFrame(TimeSpan.Zero, data, more))
            {
                return(Task.CompletedTask);
            }

            TaskCompletionSource <object> source = new TaskCompletionSource <object>();

            cancellationToken.Register(() =>
            {
                socket.SendReady -= Listener;
                source.TrySetCanceled();
            });

            void Listener(object sender, NetMQSocketEventArgs args)
            {
                if (socket.TrySendFrame(TimeSpan.Zero, data, more))
                {
                    socket.SendReady -= Listener;
                    source.TrySetResult(null);
                }
            }

            socket.SendReady += Listener;

            return(source.Task);
        }