public async Task <SocketMessage> ListenToReplyAsync(OrikivoCommandContext Context, ICriteria <SocketMessage> criteria, TimeSpan?timeout = null) { timeout = timeout ?? _timeout; TaskCompletionSource <SocketMessage> trigger = new TaskCompletionSource <SocketMessage>(); async Task Listener(SocketMessage message) { bool ensured = await criteria.EnsureAsync(Context, message).ConfigureAwait(false); if (ensured) { trigger.SetResult(message); } } Context.Client.MessageReceived += Listener; Task <SocketMessage> handler = trigger.Task; Task delay = Task.Delay(timeout.Value); Task task = await Task.WhenAny(handler, delay).ConfigureAwait(false); Context.Client.MessageReceived -= Listener; if (task == handler) { return(await handler.ConfigureAwait(false)); } else { return(null); } }