git clone https://gist.github.com/aaefc21d2c979222c1c4fe7f9b3f4943.git continue-with-and-custom-scheduler
cd continue-with-and-custom-scheduler
dotnet run
Last active
December 18, 2020 23:52
-
-
Save NikiforovAll/aaefc21d2c979222c1c4fe7f9b3f4943 to your computer and use it in GitHub Desktop.
playing with continuewith and custom synchronization context
This file contains 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.Concurrent; | |
using System.Collections.Generic; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace cancellation_demo1 | |
{ | |
public static class ContinueWith | |
{ | |
internal static void Run() | |
{ | |
// var scheduler = new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler; | |
// var scheduler = TaskScheduler.Current; | |
var scheduler = new SchedulerContainer.SynchronizationContextTaskScheduler(new SynchronizationContext()); | |
foreach (var _ in new int[]{1,2,3,4,5}) | |
{ | |
new TaskFactory(scheduler).StartNew(RunInternal).ConfigureAwait(true); | |
} | |
Console.ReadKey(); | |
} | |
internal static void RunInternal() | |
{ | |
// SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); | |
var scheduler = new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler; | |
// TaskScheduler.UnobservedTaskException | |
// SynchronizationContext.SetSynchronizationContext(null); | |
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId + $"|{Thread.CurrentThread.Name} - {Thread.CurrentThread.ThreadState}"); | |
var t = Task.Factory.StartNew(() => | |
{ | |
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId + $"|{Thread.CurrentThread.Name} - {Thread.CurrentThread.ThreadState}"); | |
}, default, TaskCreationOptions.None, TaskScheduler.Current) | |
.ContinueWith( | |
_ => | |
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId + $"|{Thread.CurrentThread.Name} - {Thread.CurrentThread.ThreadState}"), | |
TaskScheduler.Current | |
); | |
t.Wait(); | |
} | |
} | |
public static class SchedulerContainer | |
{ | |
public class SynchronizationContextTaskScheduler : TaskScheduler | |
{ | |
private ConcurrentQueue<Task> _tasks = new(); | |
private SynchronizationContext _context; | |
public SynchronizationContextTaskScheduler() : | |
this(SynchronizationContext.Current) | |
{ } | |
public SynchronizationContextTaskScheduler( | |
SynchronizationContext context) | |
{ | |
_context = context ?? throw new ArgumentNullException(nameof(context)); | |
} | |
protected override void QueueTask(Task task) | |
{ | |
// Add the task to the collection | |
_tasks.Enqueue(task); | |
// Queue up a delegate that will dequeue and execute a task | |
_context.Post(delegate | |
{ | |
Task toExecute; | |
if (_tasks.TryDequeue(out toExecute)) TryExecuteTask(toExecute); | |
}, null); | |
} | |
protected override bool TryExecuteTaskInline( | |
Task task, bool taskWasPreviouslyQueued) | |
{ | |
return SynchronizationContext.Current == _context && | |
TryExecuteTask(task); | |
} | |
public override int MaximumConcurrencyLevel { get { return 1; } } | |
protected override IEnumerable<Task> GetScheduledTasks() | |
{ | |
return _tasks.ToArray(); | |
} | |
} | |
} | |
} |
This file contains 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.Threading; | |
using System; | |
using System.Threading.Tasks; | |
using System.Collections.Generic; | |
namespace cancellation_demo1 | |
{ | |
class Program | |
{ | |
static CancellationTokenSource cts = new(); | |
static async Task Main(string[] args) | |
{ | |
ContinueWith.Run(); | |
// var task1 = Do3(); | |
// Task result = Task.WhenAny(Do2(), Do1(), Do3()); | |
// await result; | |
// System.Console.WriteLine($"Finished... {result.Status}/task1{task1.Status}"); | |
} | |
private static async Task Do2() | |
{ | |
await Task.Delay(TimeSpan.FromSeconds(2), cts.Token); | |
System.Console.WriteLine("Processed Do2"); | |
} | |
private static async Task Do1() | |
{ | |
await Task.Delay(100); | |
cts.Cancel(); | |
} | |
private static async Task Do3() | |
{ | |
await Task.Delay(0); | |
throw new Exception(nameof(Do3)); | |
} | |
} | |
} |
This file contains 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
set -e | |
desc="playing with continuewith and custom synchronization context" | |
DEMO_NAME=`basename $PWD` | |
GIST_ID=$(gh gist create --public --desc "$desc" "$@" | grep https) | |
echo $GIST_ID | |
gh gist edit $GIST_ID -f README.md |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment