using System.Threading.Tasks;
static async Task IdentifyAsync(Task task, int id)
var thread = Thread.CurrentThread;
string name = thread.IsThreadPoolThread
? "Thread pool" : thread.Name;
if (string.IsNullOrEmpty(name))
name = "#" + thread.ManagedThreadId;
Console.WriteLine("Continuation #" + id + " on: " + name + ", id: " + Thread.CurrentThread.ManagedThreadId);
public static void Main()
Thread.CurrentThread.Name = "Main thread";
Console.WriteLine("Started on: " + Thread.CurrentThread.Name + ", id: " + Thread.CurrentThread.ManagedThreadId);
var source1 = new TaskCompletionSource<int>();
IdentifyAsync(source1.Task, 1);
var source2 = new TaskCompletionSource<int>();
IdentifyAsync(source2.Task, 2);
source2.SetResultAsync(123);
Console.WriteLine("Press [return]");
public static class TaskExt
static public void SetResultAsync<T>(this TaskCompletionSource<T> tcs, T result)
FakeSynchronizationContext.Execute(() => tcs.SetResult(result));
class FakeSynchronizationContext : SynchronizationContext
private static readonly ThreadLocal<FakeSynchronizationContext> s_context =
new ThreadLocal<FakeSynchronizationContext>(() => new FakeSynchronizationContext());
private FakeSynchronizationContext() { }
public static FakeSynchronizationContext Instance { get { return s_context.Value; } }
public static void Execute(Action action)
var savedContext = SynchronizationContext.Current;
SynchronizationContext.SetSynchronizationContext(FakeSynchronizationContext.Instance);
SynchronizationContext.SetSynchronizationContext(savedContext);
public override SynchronizationContext CreateCopy()
public override void OperationStarted()
throw new NotImplementedException("OperationStarted");
public override void OperationCompleted()
throw new NotImplementedException("OperationCompleted");
public override void Post(SendOrPostCallback d, object state)
throw new NotImplementedException("Post");
public override void Send(SendOrPostCallback d, object state)
throw new NotImplementedException("Send");