-
Notifications
You must be signed in to change notification settings - Fork 31
Open
Description
When a task is awaited, the UI could repaint and trigger events. But this doesn't happen because _workItemsWaiting.WaitOne() also blocks the event queue of WPF windows. A DispatcherFrame can be pushed to continue the main dispatcher loop until this frame is canceled. That's how WPF synchronously waits for dialogs to return.
Should I propose a PR? I noticed this repo is somewhat stale.
It's available in net40 up and Windows desktop (WPF targets). So not on .net standard or Coree
Code that works for me:
private class ExclusiveSynchronizationContext : SynchronizationContext
{
private bool _done;
private EventQueue _items;
private SynchronizationContext _old;
private DispatcherFrame _dispatcherFrame;
public Exception InnerException { get; set; }
public ExclusiveSynchronizationContext(SynchronizationContext old)
{
_old = old;
ExclusiveSynchronizationContext oldEx =
old as ExclusiveSynchronizationContext;
if (null != oldEx)
{
this._items = oldEx._items;
}
else
{
this._items = new EventQueue();
}
}
public override void Send(SendOrPostCallback d, object state)
{
throw new NotSupportedException(
"We cannot send to our same thread");
}
public override void Post(SendOrPostCallback d, object state)
{
_items.Enqueue(Tuple.Create(d, state));
if (_dispatcherFrame != null)
{
_dispatcherFrame.Continue = false;
_dispatcherFrame = null;
}
}
public void EndMessageLoop()
{
Post(_ => _done = true, null);
}
public void BeginMessageLoop()
{
while (!_done)
{
EventTask task = null;
if (!_items.TryDequeue(out task))
{
task = null;
}
if (task != null)
{
task.Item1(task.Item2);
if (InnerException != null) // method threw an exeption
{
throw new AggregateException(
"AsyncBridge.Run method threw an exception.",
InnerException);
}
}
else
{
// No task to run, so we wait for the next post to cancel the dispatcher frame
_dispatcherFrame = new DispatcherFrame();
Dispatcher.PushFrame(_dispatcherFrame);
}
}
}
public override SynchronizationContext CreateCopy()
{
return this;
}
}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels