Generalize and harden ST-sync-context
\n\nCommit migrated from 247bb34a63
This commit is contained in:
parent
2d1743a2f6
commit
ffc4b00764
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.Extensions.Internal
|
||||
{
|
||||
internal class SingleThreadedSynchronizationContext : SynchronizationContext
|
||||
{
|
||||
private readonly BlockingCollection<(SendOrPostCallback Callback, object State)> _queue = new BlockingCollection<(SendOrPostCallback Callback, object State)>();
|
||||
|
||||
public override void Send(SendOrPostCallback d, object state) // Sync operations
|
||||
{
|
||||
throw new NotSupportedException($"{nameof(SingleThreadedSynchronizationContext)} does not support synchronous operations.");
|
||||
}
|
||||
|
||||
public override void Post(SendOrPostCallback d, object state) // Async operations
|
||||
{
|
||||
_queue.Add((d, state));
|
||||
}
|
||||
|
||||
public static void Run(Action action)
|
||||
{
|
||||
var previous = Current;
|
||||
var context = new SingleThreadedSynchronizationContext();
|
||||
SetSynchronizationContext(context);
|
||||
try
|
||||
{
|
||||
action();
|
||||
|
||||
while (context._queue.TryTake(out var item))
|
||||
{
|
||||
item.Callback(item.State);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
context._queue.CompleteAdding();
|
||||
SetSynchronizationContext(previous);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue