Permalink
Browse files

TaskSample - TwoItemsFirstHangsUntilCancelSecondMatchesSyncReturns

  • Loading branch information...
bobbymcr committed May 23, 2018
1 parent dc1b2a8 commit c48413b070c0b2b78e41bd182a4a07cc10991cc8
@@ -6,24 +6,43 @@ namespace TaskSample.Extensions
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
public static class FuncTaskExtensions
{
public static async Task<T> FirstAsync<T>(this IEnumerable<Func<CancellationToken, Task<T>>> funcs, Predicate<T> pred)
{
foreach (Func<CancellationToken, Task<T>> func in funcs)
var tasks = new List<Task<T>>();
T firstResult = default(T);
using (CancellationTokenSource cts = new CancellationTokenSource())
{
T result = await func(CancellationToken.None);
if (pred(result))
foreach (Func<CancellationToken, Task<T>> func in funcs)
{
return result;
if (cts.IsCancellationRequested)
{
break;
}
Func<CancellationToken, Task<T>> match = async t =>
{
T result = await func(t);
if (pred(result))
{
firstResult = result;
cts.Cancel();
}
return result;
};
Task<T> task = match(CancellationToken.None);
tasks.Add(task);
}
}
return default(T);
await Task.WhenAny(tasks);
return firstResult;
}
}
}
}
@@ -57,5 +57,25 @@ public void TwoItemsSecondMatchesSyncReturns()
task.IsCompletedSuccessfully.Should().BeTrue();
task.Result.Should().Be("good 2");
}
[Fact]
public void TwoItemsFirstHangsUntilCancelSecondMatchesSyncReturns()
{
TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
IEnumerable<Func<CancellationToken, Task<string>>> funcs = new Func<CancellationToken, Task<string>>[]
{
t =>
{
t.Register(() => tcs.SetCanceled());
return tcs.Task;
},
t => Task.FromResult("good 2")
};
Task<string> task = funcs.FirstAsync(r => r.StartsWith("good", StringComparison.Ordinal));
task.IsCompletedSuccessfully.Should().BeTrue();
task.Result.Should().Be("good 2");
}
}
}

0 comments on commit c48413b

Please sign in to comment.