ConcurrencyAbstractionLayerImpl
using System.Reactive.Disposables;
using System.Runtime.CompilerServices;
using System.Threading;
namespace System.Reactive.Concurrency
{
internal sealed class ConcurrencyAbstractionLayerImpl : IConcurrencyAbstractionLayer
{
[System.Runtime.CompilerServices.NullableContext(2)]
[System.Runtime.CompilerServices.Nullable(0)]
private sealed class WorkItem
{
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
[field: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
public Action<object> Action {
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
get;
}
public object State { get; }
public WorkItem([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] Action<object> action, object state)
{
Action = action;
State = state;
}
}
private sealed class Timer : IDisposable
{
[System.Runtime.CompilerServices.Nullable(2)]
private volatile object _state;
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
private Action<object> _action;
private SingleAssignmentDisposableValue _timer;
[System.Runtime.CompilerServices.Nullable(1)]
private static readonly object DisposedState = new object();
[System.Runtime.CompilerServices.NullableContext(2)]
public Timer([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] Action<object> action, object state, TimeSpan dueTime)
{
_state = state;
_action = action;
_timer.Disposable = new System.Threading.Timer(delegate(object this) {
((Timer)this).Tick();
}, this, dueTime, TimeSpan.FromMilliseconds(-1));
}
private void Tick()
{
try {
object state = _state;
if (state != DisposedState)
_action(state);
} finally {
_timer.Dispose();
}
}
public void Dispose()
{
_timer.Dispose();
_action = Stubs<object>.Ignore;
_state = DisposedState;
}
}
private sealed class PeriodicTimer : IDisposable
{
[System.Runtime.CompilerServices.Nullable(1)]
private Action _action;
[System.Runtime.CompilerServices.Nullable(2)]
private volatile System.Threading.Timer _timer;
[System.Runtime.CompilerServices.NullableContext(1)]
public PeriodicTimer(Action action, TimeSpan period)
{
_action = action;
_timer = new System.Threading.Timer(delegate(object this) {
((PeriodicTimer)this).Tick();
}, this, period, period);
}
private void Tick()
{
_action();
}
public void Dispose()
{
System.Threading.Timer timer = _timer;
if (timer != null) {
_action = Stubs.Nop;
_timer = null;
timer.Dispose();
}
}
}
private sealed class FastPeriodicTimer : IDisposable
{
[System.Runtime.CompilerServices.Nullable(1)]
private readonly Action _action;
private volatile bool _disposed;
[System.Runtime.CompilerServices.NullableContext(1)]
public FastPeriodicTimer(Action action)
{
_action = action;
Thread thread = new Thread(delegate(object this) {
((FastPeriodicTimer)this).Loop();
});
thread.Name = "Rx-FastPeriodicTimer";
thread.IsBackground = true;
thread.Start(this);
}
private void Loop()
{
while (!_disposed) {
_action();
}
}
public void Dispose()
{
_disposed = true;
}
}
public bool SupportsLongRunning => true;
[System.Runtime.CompilerServices.NullableContext(1)]
public IDisposable StartTimer([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] Action<object> action, [System.Runtime.CompilerServices.Nullable(2)] object state, TimeSpan dueTime)
{
return new Timer(action, state, Normalize(dueTime));
}
[System.Runtime.CompilerServices.NullableContext(1)]
public IDisposable StartPeriodicTimer(Action action, TimeSpan period)
{
if (period < TimeSpan.Zero)
throw new ArgumentOutOfRangeException("period");
if (period == TimeSpan.Zero)
return new FastPeriodicTimer(action);
return new PeriodicTimer(action, period);
}
[System.Runtime.CompilerServices.NullableContext(1)]
public IDisposable QueueUserWorkItem([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] Action<object> action, [System.Runtime.CompilerServices.Nullable(2)] object state)
{
ThreadPool.QueueUserWorkItem(delegate(object itemObject) {
WorkItem workItem = (WorkItem)itemObject;
workItem.Action(workItem.State);
}, new WorkItem(action, state));
return Disposable.Empty;
}
public void Sleep(TimeSpan timeout)
{
Thread.Sleep(Normalize(timeout));
}
[System.Runtime.CompilerServices.NullableContext(1)]
public IStopwatch StartStopwatch()
{
return new StopwatchImpl();
}
[System.Runtime.CompilerServices.NullableContext(2)]
public void StartThread([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] Action<object> action, object state)
{
Thread thread = new Thread(delegate(object itemObject) {
WorkItem workItem = (WorkItem)itemObject;
workItem.Action(workItem.State);
});
thread.IsBackground = true;
thread.Start(new WorkItem(action, state));
}
private static TimeSpan Normalize(TimeSpan dueTime)
{
if (!(dueTime < TimeSpan.Zero))
return dueTime;
return TimeSpan.Zero;
}
}
}