Created
July 10, 2018 08:22
-
-
Save JimBobSquarePants/ec7e267b797451271747efd87b5e80ac to your computer and use it in GitHub Desktop.
Attempt at demoing returning only completed tasks from a collection.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
namespace TaskTest | |
{ | |
class Program | |
{ | |
private static Random r = new Random(); | |
static async Task Main(string[] args) | |
{ | |
var tasks = new Task<IEnumerable<int>>[] { ExternalTask(), ExternalTask(), ExternalTask(), ExternalTask(), ExternalTask() }; | |
var t2 = await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(3000)); | |
var completedResults = tasks | |
.Where(t => t.Status == TaskStatus.RanToCompletion) | |
.Select(t => t.Result) | |
.ToList(); | |
foreach (var item in completedResults) | |
{ | |
Console.WriteLine($"Task completed with {item.First()} delay."); | |
} | |
Console.ReadLine(); | |
} | |
private static Task<IEnumerable<int>> ExternalTask() | |
{ | |
int delay = r.Next(0, 6000); | |
Task.Delay(delay); | |
var enumerable = Enumerable.Repeat(delay, 6); | |
return Task.FromResult(enumerable); | |
} | |
} | |
} |
Complete working demo. await
all the things!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace TaskDemo
{
class Program
{
private static Random r = new Random();
private const int delay = 3000;
static async Task Main(string[] args)
{
var tasks = new Task<IEnumerable<int>>[] { ExternalTask(), ExternalTask(), ExternalTask(), ExternalTask(), ExternalTask() };
// Gather the results that complete within the timespan interval.
var completedResults = await WhenAll(tasks, TimeSpan.FromMilliseconds(3000));
Console.WriteLine($"Completed Tasks within {delay}:");
foreach (var item in completedResults)
{
Console.WriteLine($"Task completed with {item.First()} milliseconds delay.");
}
Console.ReadLine();
}
private async static Task<IEnumerable<int>> ExternalTask()
{
// Randomly delay the task to anywhere between 0 and 2x the delay
int milliseconds = r.Next(0, 2 * delay);
Console.WriteLine($"Task will take {milliseconds} milliseconds.");
await Task.Delay(milliseconds);
var enumerable = Enumerable.Repeat(milliseconds, 6);
return enumerable;
}
/// <summary>
/// Creates a task that will complete when <see cref="Task{TResult[]}"/> the timeout interval has passed.
/// </summary>
/// <typeparam name="TResult">The type of result.</typeparam>
/// <param name="tasks">The enumerable of tasks to attempt to complete.</param>
/// <param name="timeout">The timeout.</param>
/// <returns>The <paramref name="tasks"/> completed within the timespan limit.</returns>
private static async Task<TResult[]> WhenAll<TResult>(IEnumerable<Task<TResult>> tasks, TimeSpan timeout)
{
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(timeout));
return tasks
.Where(t => t.Status == TaskStatus.RanToCompletion)
.Select(t => t.Result)
.ToArray();
}
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Await Task.Delay: ExternalTask is running synchronously. It kicks off a task delay but doesn't await on it.
You could replace that with a
Thread.Sleep
instead or make the methodasync
and await onTask.Delay
. Obviously in production appsThread.Sleep
would get Ben Adams to come after you.