Skip to content

Commit 3a205bf

Browse files
committed
Merge branch 'develop' of https://github.com/ReferenceType/NetworkExperiments into develop
2 parents 4723312 + bfe5a72 commit 3a205bf

File tree

4 files changed

+246
-0
lines changed

4 files changed

+246
-0
lines changed

AsyncAutoResetEvent.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
public class AsyncAutoResetEvent
2+
{
3+
private readonly static Task completed = Task.FromResult(true);
4+
private readonly ConcurrentQueue<TaskCompletionSource<bool>> waiters = new ConcurrentQueue<TaskCompletionSource<bool>>();
5+
private bool signaled;
6+
7+
/// <summary>
8+
/// Initializes a new instance of the <see cref="AsyncAutoResetEvent"/>
9+
/// class with a Boolean value indicating whether to set the initial state to signaled.
10+
/// </summary>
11+
/// <param name="signaled">if set to <c>true</c> [signaled].</param>
12+
public AsyncAutoResetEvent(bool signaled = false)
13+
{
14+
this.signaled = signaled;
15+
}
16+
17+
18+
/// <summary>
19+
/// Switches state machine of the current task until the event is signaled,
20+
/// a signal.
21+
/// </summary>
22+
/// <returns></returns>
23+
public Task WaitAsync()
24+
{
25+
lock (waiters)
26+
{
27+
if (signaled)
28+
{
29+
signaled = false;
30+
return completed;
31+
}
32+
else
33+
{
34+
var tcs = new TaskCompletionSource<bool>();
35+
waiters.Enqueue(tcs);
36+
return tcs.Task;
37+
}
38+
}
39+
}
40+
41+
/// <summary>
42+
/// Sets the state of the event to signaled, allowing one or more waiting tasks to proceed.
43+
/// </summary>
44+
public void Set()
45+
{
46+
TaskCompletionSource<bool> toRelease = null;
47+
lock (waiters)
48+
{
49+
if (waiters.Count > 0)
50+
{
51+
waiters.TryDequeue(out toRelease);
52+
}
53+
54+
else if (!signaled)
55+
signaled = true;
56+
57+
if (toRelease != null)
58+
toRelease.SetResult(true);
59+
}
60+
61+
}
62+
}

AsyncManualResetEvent.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
public class AsyncManualResetEvent
2+
{
3+
private volatile TaskCompletionSource<bool> completionSource = new TaskCompletionSource<bool>();
4+
5+
/// <summary>
6+
/// Initializes a new instance of the <see cref="AsyncManualResetEvent"/> class with
7+
/// a Boolean value indicating whether to set the initial state to signaled.
8+
/// </summary>
9+
/// <param name="signaled">if set to <c>true</c> [signaled].</param>
10+
public AsyncManualResetEvent( bool signaled )
11+
{
12+
if (signaled)
13+
completionSource.TrySetResult(true);
14+
}
15+
16+
/// <summary>
17+
/// Waits the asynchronous.
18+
/// </summary>
19+
/// <returns></returns>
20+
public Task WaitAsync() { return completionSource.Task; }
21+
22+
/// <summary>
23+
/// Sets the state of the event to signaled, allowing one or more waiting tasks to proceed.
24+
/// </summary>
25+
public void Set() { completionSource.TrySetResult(true); }
26+
27+
/// <summary>
28+
/// Sets the state of the event to non signaled, allowing one or more waiting tasks to await.
29+
/// </summary>
30+
public void Reset()
31+
{
32+
while (true)
33+
{
34+
var tcs = completionSource;
35+
if (!tcs.Task.IsCompleted ||
36+
Interlocked.CompareExchange(ref completionSource, new TaskCompletionSource<bool>(), tcs) == tcs)
37+
return;
38+
}
39+
}
40+
}

Clock.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
public class Clock
2+
{
3+
public Action OnTick;
4+
private System.Threading.Timer timer;
5+
private readonly int tickFrequency;
6+
public Clock(int tickFrequency)
7+
{
8+
timer = new System.Threading.Timer(Tick,null,tickFrequency,tickFrequency);
9+
this.tickFrequency = tickFrequency;
10+
}
11+
12+
private void Tick(object state)
13+
{
14+
OnTick?.Invoke();
15+
}
16+
17+
public void Awake()
18+
{
19+
timer.Change(tickFrequency, tickFrequency);
20+
}
21+
public void Pause()
22+
{
23+
timer.Change(Timeout.Infinite, tickFrequency);
24+
}
25+
26+
}

Temp.cs

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
using System;
2+
using System.Collections.Concurrent;
3+
using System.Diagnostics;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
7+
namespace ExpressionTree
8+
{
9+
public class Timer
10+
{
11+
static readonly ConcurrentDictionary<TimerInstance, string> activeTimers = new ConcurrentDictionary<TimerInstance, string>();
12+
static readonly ConcurrentBag<TimerInstance> timerPool = new ConcurrentBag<TimerInstance>();
13+
14+
static readonly AutoResetEvent a = new AutoResetEvent(false);
15+
static int Number = 0;
16+
static Timer()
17+
{
18+
TimerInstance.rec = activeTimers;
19+
StartTimerThread();
20+
}
21+
22+
private static void StartTimerThread()
23+
{
24+
Thread t = new Thread(() =>
25+
{
26+
SpinWait sw = new SpinWait();
27+
Stopwatch stopwatch = new Stopwatch();
28+
while (true)
29+
{
30+
a.WaitOne();
31+
stopwatch.Restart();
32+
Thread.Sleep(10);
33+
//sw.SpinOnce();
34+
//stopwatch.Stop();
35+
36+
Tick(stopwatch);
37+
}
38+
});
39+
40+
// t.Start();
41+
Looper();
42+
43+
}
44+
private async static void Looper()
45+
{
46+
Stopwatch stopwatch = new Stopwatch();
47+
while (true)
48+
{
49+
50+
stopwatch.Restart();
51+
await Task.Delay(10).ConfigureAwait(false);
52+
Tick(stopwatch);
53+
}
54+
}
55+
56+
private static void Tick(Stopwatch sw)
57+
{
58+
if(activeTimers.Count == 0)
59+
return;
60+
61+
a.Set();
62+
foreach (var item in activeTimers)
63+
{
64+
item.Key.Tick((int)sw.ElapsedMilliseconds);
65+
}
66+
}
67+
68+
private static TimerInstance GetTimer()
69+
{
70+
var timer = new TimerInstance();
71+
timer.number = Interlocked.Increment(ref Number);
72+
return timer;
73+
}
74+
75+
public static void Wait(int miliseconds,Action OnCompleted)
76+
{
77+
var timer = GetTimer();
78+
timer.remaining = miliseconds;
79+
timer.Completed += OnCompleted;
80+
activeTimers.TryAdd(timer, null);
81+
a.Set();
82+
}
83+
84+
class TimerInstance
85+
{
86+
public int remaining;
87+
public Action Completed;
88+
public static ConcurrentDictionary<TimerInstance, string> rec;
89+
public static ConcurrentBag<TimerInstance> timerPool;
90+
public int number;
91+
public void Tick(int dt)
92+
{
93+
remaining -= dt;
94+
if (remaining <= 0)
95+
{
96+
Complete();
97+
}
98+
}
99+
100+
private void Complete()
101+
{
102+
rec.TryRemove(this, out _);
103+
Completed?.Invoke();
104+
Reset();
105+
}
106+
107+
public void Reset()
108+
{
109+
//remaining = 1000;
110+
Completed = null;
111+
}
112+
public override int GetHashCode()
113+
{
114+
return number;
115+
}
116+
}
117+
}
118+
}

0 commit comments

Comments
 (0)