You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
3.9 KiB
152 lines
3.9 KiB
5 years ago
|
#if FAT
|
||
|
|
||
|
using System;
|
||
|
using System.Threading;
|
||
|
|
||
|
namespace LinqInternal.Threading.Needles
|
||
|
{
|
||
|
[Serializable]
|
||
|
[System.Diagnostics.DebuggerNonUserCode]
|
||
|
internal class FutureAction : LazyAction
|
||
|
{
|
||
|
private readonly Action<Action> _schedule;
|
||
|
private int _status;
|
||
|
|
||
|
public FutureAction(Action action)
|
||
|
: base(action)
|
||
|
{
|
||
|
_schedule = Schedule;
|
||
|
}
|
||
|
|
||
|
public FutureAction(Action action, bool autoSchedule)
|
||
|
: base(action)
|
||
|
{
|
||
|
_schedule = Schedule;
|
||
|
if (autoSchedule)
|
||
|
{
|
||
|
Schedule();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public FutureAction(Action<Action> schedule, Action action)
|
||
|
: base(action)
|
||
|
{
|
||
|
_schedule = schedule;
|
||
|
}
|
||
|
|
||
|
public FutureAction(Action<Action> schedule, Action action, bool autoSchedule)
|
||
|
: base(action)
|
||
|
{
|
||
|
_schedule = schedule;
|
||
|
if (autoSchedule)
|
||
|
{
|
||
|
Schedule();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void Execute()
|
||
|
{
|
||
|
if (Interlocked.CompareExchange(ref _status, 1, 0) != 0)
|
||
|
{
|
||
|
base.Wait();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
base.Execute();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override void Execute(Action beforeInitialize)
|
||
|
{
|
||
|
if (Interlocked.CompareExchange(ref _status, 1, 0) != 0)
|
||
|
{
|
||
|
base.Wait();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
base.Execute(beforeInitialize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public bool Schedule()
|
||
|
{
|
||
|
if (Interlocked.CompareExchange(ref _status, 1, 0) != 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
_schedule(base.Execute);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public override void Wait()
|
||
|
{
|
||
|
Execute();
|
||
|
}
|
||
|
|
||
|
public override void Wait(CancellationToken cancellationToken)
|
||
|
{
|
||
|
if (Interlocked.CompareExchange(ref _status, 1, 0) != 0)
|
||
|
{
|
||
|
base.Wait(cancellationToken);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
base.Execute();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void Wait(int milliseconds)
|
||
|
{
|
||
|
if (Interlocked.CompareExchange(ref _status, 1, 0) != 0)
|
||
|
{
|
||
|
base.Wait(milliseconds);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
var start = ThreadingHelper.TicksNow();
|
||
|
base.Execute();
|
||
|
milliseconds = milliseconds - (int)ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start);
|
||
|
if (milliseconds > 0)
|
||
|
{
|
||
|
base.Wait(milliseconds);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void Wait(TimeSpan timeout)
|
||
|
{
|
||
|
Wait((int)timeout.TotalMilliseconds);
|
||
|
}
|
||
|
|
||
|
public override void Wait(int milliseconds, CancellationToken cancellationToken)
|
||
|
{
|
||
|
if (Interlocked.CompareExchange(ref _status, 1, 0) != 0)
|
||
|
{
|
||
|
base.Wait(milliseconds, cancellationToken);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
var start = ThreadingHelper.TicksNow();
|
||
|
base.Execute();
|
||
|
milliseconds = milliseconds - (int)ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start);
|
||
|
if (milliseconds > 0)
|
||
|
{
|
||
|
base.Wait(milliseconds, cancellationToken);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void Wait(TimeSpan timeout, CancellationToken cancellationToken)
|
||
|
{
|
||
|
Wait((int)timeout.TotalMilliseconds, cancellationToken);
|
||
|
}
|
||
|
|
||
|
private static void Schedule(Action action)
|
||
|
{
|
||
|
var waitCallback = new WaitCallback(_ => action());
|
||
|
ThreadPool.QueueUserWorkItem(waitCallback);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|