/// <summary> /// Tells the <see cref="MessageCollector"/> to begin collecting messages asynchronously. /// </summary> /// <param name="filter">The raw filter that will be used when comparing messages.</param> /// <param name="options">The options that will be used to set up the <see cref="MessageCollector"/>.</param> /// <returns>A <see cref="TimeSpan"/> that represents the amount of time that has passed for this method.</returns> public async Task <MessageMatchCollection> CollectAsync(FilterCollectionDelegate filter, CollectionOptions options = null) { options ??= CollectionOptions.Default; var matches = new MessageMatchCollection(); var timer = new AsyncTimer(options.Timeout); var complete = new TaskCompletionSource <bool>(); int index = 0; async Task HandleAsync(SocketMessage arg) { bool isSuccess = filter.Invoke(arg, matches, index); if (isSuccess || options.IncludeFailedMatches) { matches.Add(new MessageMatch(arg, index, isSuccess, timer.ElapsedTime)); } if (isSuccess && options.ResetTimeoutOnMatch) { timer.Reset(); } if (options.Capacity.HasValue && matches.Count == options.Capacity.Value) { timer.Stop(); complete.SetResult(true); } index++; } _client.MessageReceived += HandleAsync; if (options.Timeout.HasValue) { timer.Start(); } await Task.WhenAny(timer.CompletionSource.Task, complete.Task); _client.MessageReceived -= HandleAsync; return(matches); }
/// <summary> /// Tells the <see cref="MessageCollector"/> to asynchronously 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> /// <returns>A <see cref="TimeSpan"/> that represents the amount of time that has passed for this method.</returns> public async Task <MessageMatch> MatchAsync(FilterDelegate filter, MatchOptions options = null) { options ??= MatchOptions.Default; MessageMatch match = null; var timer = new AsyncTimer(options.Timeout); var complete = new TaskCompletionSource <bool>(); int attempts = 0; async Task HandleAsync(SocketMessage arg) { bool isSuccess = filter.Invoke(arg, attempts); match = new MessageMatch(arg, attempts, isSuccess, timer.ElapsedTime); if (isSuccess) { complete.SetResult(true); } 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; return(match); }
/// <summary> /// Starts an asynchronous <see cref="MessageSession"/> for this <see cref="MessageCollector"/>. /// </summary> /// <param name="session">The <see cref="MessageSession"/> that will be used for this <see cref="MessageCollector"/>.</param> /// <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> /// <returns>A <see cref="TimeSpan"/> that represents the amount of time that has passed for this method.</returns> public async Task <TimeSpan> RunSessionAsync(MessageSession session, FilterDelegate filter, MatchOptions options = null) { if (session == null) { throw new ArgumentNullException(nameof(session), "The specified MessageSession cannot be null"); } options ??= MatchOptions.Default; SocketMessage previous = null; var timer = new AsyncTimer(options.Timeout); var complete = new TaskCompletionSource <bool>(); await session.OnStartAsync(); int index = 0; async Task HandleAsync(SocketMessage arg) { bool filterSuccess = filter.Invoke(arg, index); previous = arg; if (filterSuccess) { SessionResult result = await session.OnMessageReceivedAsync(arg); switch (result) { case SessionResult.Success: complete.SetResult(true); break; case SessionResult.Fail: complete.SetResult(false); break; } } if (options.ResetTimeoutOnAttempt) { timer.Reset(); } index++; } _client.MessageReceived += HandleAsync; if (options.Timeout.HasValue) { timer.Start(); } await Task.WhenAny(timer.CompletionSource.Task, complete.Task); _client.MessageReceived -= HandleAsync; if (timer.Elapsed) { await session.OnTimeoutAsync(previous); } return(timer.ElapsedTime); }