Skip to content

Instantly share code, notes, and snippets.

@kekekeks
Last active January 9, 2020 19:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kekekeks/c244a278cf73c9af444d3d7397bf858f to your computer and use it in GitHub Desktop.
Save kekekeks/c244a278cf73c9af444d3d7397bf858f to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
static class AsyncMainHelper
{
class Ctx : SynchronizationContext
{
BlockingCollection<Action> _callbacks = new BlockingCollection<Action>();
Thread _mainThread = Thread.CurrentThread;
public override void Send(SendOrPostCallback d, object state)
{
if (Thread.CurrentThread == _mainThread)
d(state);
else
{
var tcs = new TaskCompletionSource<int>();
_callbacks.Add(() =>
{
try
{
d(state);
tcs.SetResult(0);
}
catch (Exception e)
{
tcs.SetException(e);
}
});
tcs.Task.Wait();
}
}
public override void Post(SendOrPostCallback d, object state)
{
_callbacks.Add(() => d(state));
}
public void DoJobs() => _callbacks.Take()();
}
public static void Run(Func<Task> asyncMain)
{
var ctx = new Ctx();
SynchronizationContext.SetSynchronizationContext(ctx);
var task = asyncMain();
while (!task.IsCompleted)
ctx.DoJobs();
}
}
public static class Program
{
public static void Main()
{
Console.WriteLine("Actual main thread id " + Thread.CurrentThread.ManagedThreadId);
AsyncMainHelper.Run(AsyncMain);
}
private static async Task AsyncMain()
{
Console.WriteLine("Initial thread id " + Thread.CurrentThread.ManagedThreadId);
await Task.Delay(100);
Console.WriteLine("Thread id after await " + Thread.CurrentThread.ManagedThreadId);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment