Skip to content

Instantly share code, notes, and snippets.

@lbargaoanu
Created November 7, 2019 08:53
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 lbargaoanu/6902136d5b1450f4ea081840f6517564 to your computer and use it in GitHub Desktop.
Save lbargaoanu/6902136d5b1450f4ea081840f6517564 to your computer and use it in GitHub Desktop.
using System;
using System.Threading;
using System.Collections.Concurrent;
using System.Diagnostics;
namespace UiPath.CoreIpc.Tests
{
public class GuiLikeSyncContext : SynchronizationContext
{
private readonly BlockingCollection<(SendOrPostCallback Callback, object State)> _workQueue = new BlockingCollection<(SendOrPostCallback, object)>();
private static readonly GuiLikeSyncContext Instance = new GuiLikeSyncContext();
public static IDisposable Install() => new RevertSyncContext();
sealed class RevertSyncContext : IDisposable
{
public SynchronizationContext SavedContext { get; }
public RevertSyncContext()
{
SavedContext = Current;
SetSynchronizationContext(Instance);
}
public void Dispose()
{
SetSynchronizationContext(SavedContext);
}
}
private GuiLikeSyncContext()
{
new Thread(_ =>
{
Install();
while(true)
{
ProcessItem();
}
})
{ Name = "GuiThread", IsBackground = true }
.Start();
}
private void ProcessItem()
{
var pair = _workQueue.Take();
var callback = pair.Callback;
lock(callback)
{
try
{
callback(pair.State);
}
catch(Exception ex)
{
Trace.WriteLine(ex.ToString());
}
Monitor.Pulse(callback);
}
}
public override void Post(SendOrPostCallback d, object state)
{
Trace.WriteLine("MySynchronizationContext.Post");
_workQueue.Add((d, state));
}
public override void Send(SendOrPostCallback d, object state)
{
Trace.WriteLine("MySynchronizationContext.Send");
lock(d)
{
_workQueue.Add((d, state));
Monitor.Wait(d);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment