/// <summary> /// Tells the <see cref="MessageCollector"/> to attempt to match a single message. /// </summary> /// <param name="filter">The raw filter that will be used to compare messages.</param> /// <param name="options">The options that will be used to set up the <see cref="MessageCollector"/>.</param> public async Task <FilterMatch> TryFilterAsync(FilterDelegate filter, FilterOptions options = null) { options ??= FilterOptions.Default; FilterMatch match = null; AsyncTimer timer = new AsyncTimer(options.Timeout); TaskCompletionSource <bool> complete = new TaskCompletionSource <bool>(); int attempts = 0; async Task HandleAsync(SocketMessage arg) { bool isSuccess = filter.Invoke(arg, attempts); match = new FilterMatch(arg, attempts, isSuccess); if (isSuccess) { complete.SetResult(true); } else if (options.MaxAttempts.HasValue) { if (attempts == options.MaxAttempts.Value) { complete.SetResult(false); } } if (options.ResetTimeoutOnAttempt) { timer.Reset(); } attempts++; } _client.MessageReceived += HandleAsync; if (options.Timeout.HasValue) { timer.Start(); } await Task.WhenAny(timer.CompletionSource.Task, complete.Task); _client.MessageReceived -= HandleAsync; ElapsedTime = timer.ElapsedTime; return(match); }
/// <summary> /// Starts a message handler session for this <see cref="MessageCollector"/>. /// </summary> /// <param name="filter">The filter that will be used to compare messages.</param> /// <param name="options">The options that will be used to set up the <see cref="MessageCollector"/>.</param> public async Task MatchAsync(FilterDelegate filter, SessionOptions options = null) { options ??= SessionOptions.Default; FilterMatch match = null; var timer = new AsyncTimer(options.Timeout); var complete = new TaskCompletionSource <bool>(); await options.Session.OnStartAsync(); int index = 0; async Task HandleAsync(SocketMessage arg) { bool filterSuccess = filter.Invoke(arg, index); match = new FilterMatch(arg, index, filterSuccess); if (filterSuccess) { MatchResult result = await options.Session.InvokeAsync(arg); switch (result) { case MatchResult.Fail: complete.SetResult(false); break; case MatchResult.Success: complete.SetResult(true); break; case MatchResult.Continue: default: break; } } if (options.ResetTimeoutOnAttempt) { timer.Reset(); } index++; } _client.MessageReceived += HandleAsync; if (options.Timeout.HasValue) { timer.Start(); } Task <bool> possible = await Task.WhenAny(timer.CompletionSource.Task, complete.Task); _client.MessageReceived -= HandleAsync; ElapsedTime = timer.ElapsedTime; if (timer.Elapsed) { await options.Session.OnTimeoutAsync(match?.Message); } Console.WriteLine("Match handled."); }