Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
TaskReplicator.cs
Go to the documentation of this file.
2
4
5internal sealed class TaskReplicator
6{
7 public delegate void ReplicatableUserAction<TState>(ref TState replicaState, int timeout, out bool yieldedBeforeCompletion);
8
9 private abstract class Replica
10 {
11 protected readonly TaskReplicator _replicator;
12
13 protected readonly int _timeout;
14
15 protected int _remainingConcurrency;
16
17 protected volatile Task _pendingTask;
18
19 protected Replica(TaskReplicator replicator, int maxConcurrency, int timeout)
20 {
21 _replicator = replicator;
23 _remainingConcurrency = maxConcurrency - 1;
24 _pendingTask = new Task(delegate(object s)
25 {
26 ((Replica)s).Execute();
27 }, this);
28 _replicator._pendingReplicas.Enqueue(this);
29 }
30
35
36 public void Wait()
37 {
38 Task pendingTask;
39 while ((pendingTask = _pendingTask) != null)
40 {
41 pendingTask.Wait();
42 }
43 }
44
45 public void Execute()
46 {
47 try
48 {
50 {
53 }
54 ExecuteAction(out var yieldedBeforeCompletion);
55 if (yieldedBeforeCompletion)
56 {
57 _pendingTask = new Task(delegate(object s)
58 {
59 ((Replica)s).Execute();
62 }
63 else
64 {
65 _replicator._stopReplicating = true;
66 _pendingTask = null;
67 }
68 }
69 catch (Exception item)
70 {
71 LazyInitializer.EnsureInitialized(ref _replicator._exceptions).Enqueue(item);
73 {
74 _replicator._stopReplicating = true;
75 }
76 _pendingTask = null;
77 }
78 }
79
80 protected abstract void CreateNewReplica();
81
82 protected abstract void ExecuteAction(out bool yieldedBeforeCompletion);
83 }
84
85 private sealed class Replica<TState> : Replica
86 {
88
89 private TState _state;
90
91 public Replica(TaskReplicator replicator, int maxConcurrency, int timeout, ReplicatableUserAction<TState> action)
92 : base(replicator, maxConcurrency, timeout)
93 {
95 }
96
102
103 protected override void ExecuteAction(out bool yieldedBeforeCompletion)
104 {
105 _action(ref _state, _timeout, out yieldedBeforeCompletion);
106 }
107 }
108
109 private readonly TaskScheduler _scheduler;
110
111 private readonly bool _stopOnFirstFailure;
112
114
116
117 private bool _stopReplicating;
118
119 private TaskReplicator(ParallelOptions options, bool stopOnFirstFailure)
120 {
121 _scheduler = options.TaskScheduler ?? TaskScheduler.Current;
122 _stopOnFirstFailure = stopOnFirstFailure;
123 }
124
125 public static void Run<TState>(ReplicatableUserAction<TState> action, ParallelOptions options, bool stopOnFirstFailure)
126 {
128 {
129 int timeout = 2147483646;
130 TState replicaState = default(TState);
131 action(ref replicaState, timeout, out var yieldedBeforeCompletion);
132 if (yieldedBeforeCompletion)
133 {
134 throw new Exception("Replicated tasks cannot yield in this single-threaded browser environment");
135 }
136 return;
137 }
138 int maxConcurrency = ((options.EffectiveMaxConcurrencyLevel > 0) ? options.EffectiveMaxConcurrencyLevel : int.MaxValue);
139 TaskReplicator taskReplicator = new TaskReplicator(options, stopOnFirstFailure);
140 new Replica<TState>(taskReplicator, maxConcurrency, 1073741823, action).Start();
141 Replica result;
142 while (taskReplicator._pendingReplicas.TryDequeue(out result))
143 {
144 result.Wait();
145 }
146 if (taskReplicator._exceptions != null)
147 {
148 throw new AggregateException(taskReplicator._exceptions);
149 }
150 }
151
153 {
154 int processorCount = Environment.ProcessorCount;
155 int tickCount = Environment.TickCount;
156 return 100 + tickCount % processorCount * 50;
157 }
158}
static int ProcessorCount
static int TickCount
Replica(TaskReplicator replicator, int maxConcurrency, int timeout)
void ExecuteAction(out bool yieldedBeforeCompletion)
override void ExecuteAction(out bool yieldedBeforeCompletion)
Replica(TaskReplicator replicator, int maxConcurrency, int timeout, ReplicatableUserAction< TState > action)
readonly ReplicatableUserAction< TState > _action
delegate void ReplicatableUserAction< TState >(ref TState replicaState, int timeout, out bool yieldedBeforeCompletion)
TaskReplicator(ParallelOptions options, bool stopOnFirstFailure)
static void Run< TState >(ReplicatableUserAction< TState > action, ParallelOptions options, bool stopOnFirstFailure)
readonly ConcurrentQueue< Replica > _pendingReplicas
ConcurrentQueue< Exception > _exceptions