Created
July 10, 2013 15:26
-
-
Save hanishi/5967246 to your computer and use it in GitHub Desktop.
And here is the Synchronizer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using Microsoft.AspNet.SignalR.Client.Hubs; | |
using Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
namespace SignalR | |
{ | |
class Synchronizer : IHubProxy | |
{ | |
private IHubProxy HubProxy { get; set; } | |
private State _state; | |
private readonly AutoResetEvent _auto = new AutoResetEvent(false); | |
private CancellationTokenSource CancellationTokenSource { get; set; } | |
internal Synchronizer(IHubProxy hubProxy) | |
{ | |
HubProxy = hubProxy; | |
_state = new Paused(this); | |
CancellationTokenSource = new CancellationTokenSource(); | |
} | |
public Task Invoke(string method, params object[] args) | |
{ | |
return _state.Invoke(method, args); | |
} | |
public Task<T> Invoke<T>(string method, params object[] args) | |
{ | |
return _state.Invoke<T>(method, args); | |
} | |
public Subscription Subscribe(string eventName) | |
{ | |
return HubProxy.Subscribe(eventName); | |
} | |
public JToken this[string name] | |
{ | |
get { return HubProxy[name]; } | |
set { HubProxy[name] = value; } | |
} | |
public JsonSerializer JsonSerializer | |
{ | |
get { return HubProxy.JsonSerializer; } | |
} | |
public void Pause() | |
{ | |
_state.Pause(); | |
} | |
public void Resume() | |
{ | |
_state.Resume(); | |
} | |
public void Stop() | |
{ | |
_state.Stop(); | |
} | |
private abstract class State | |
{ | |
public abstract Task Invoke(string method, params object[] args); | |
public abstract Task<T> Invoke<T>(string method, params object[] args); | |
public abstract void Pause(); | |
public abstract void Resume(); | |
public abstract void Stop(); | |
} | |
private class Resumed : State | |
{ | |
private Synchronizer Synchronizer { get; set; } | |
public Resumed(Synchronizer synchronizer) | |
{ | |
Synchronizer = synchronizer; | |
} | |
public override Task Invoke(string method, params object[] args) | |
{ | |
return Synchronizer.HubProxy.Invoke(method, args); | |
} | |
public override Task<T> Invoke<T>(string method, params object[] args) | |
{ | |
return Synchronizer.HubProxy.Invoke<T>(method, args); | |
} | |
public override void Pause() | |
{ | |
Synchronizer._state = new Paused(Synchronizer); | |
Console.WriteLine("Paused!"); | |
} | |
public override void Resume() | |
{ | |
throw new InvalidOperationException("already resumed"); | |
} | |
public override void Stop() | |
{ | |
throw new InvalidOperationException("Pause() before Stop()"); | |
} | |
} | |
private class Paused : State | |
{ | |
private Synchronizer Synchronizer { get; set; } | |
public Paused(Synchronizer synchronizer) | |
{ | |
Synchronizer = synchronizer; | |
} | |
public override Task Invoke(string method, params object[] args) | |
{ | |
Console.WriteLine("Invoke Paused!"); | |
Synchronizer._auto.WaitOne(); | |
return Synchronizer.HubProxy.Invoke(method, args); | |
} | |
public override Task<T> Invoke<T>(string method, params object[] args) | |
{ | |
Console.WriteLine("Invoke Paused!"); | |
Synchronizer._auto.WaitOne(); | |
return Synchronizer.HubProxy.Invoke<T>(method, args); | |
} | |
public override void Pause() | |
{ | |
throw new InvalidOperationException("already paused"); | |
} | |
public override void Resume() | |
{ | |
Console.WriteLine("Resumed!"); | |
Synchronizer._state = new Resumed(Synchronizer); | |
Synchronizer._auto.Set(); | |
} | |
public override void Stop() | |
{ | |
//Console.WriteLine("Stopped!"); | |
Synchronizer._state = new Stopped(Synchronizer); | |
Synchronizer._auto.Set(); | |
Synchronizer.CancellationTokenSource.Cancel(); | |
} | |
} | |
private class Stopped : State | |
{ | |
private Synchronizer Synchronizer { get; set; } | |
private CancellationToken ct; | |
public Stopped(Synchronizer synchronizer) | |
{ | |
Synchronizer = synchronizer; | |
ct = Synchronizer.CancellationTokenSource.Token; | |
} | |
public override Task Invoke(string method, params object[] args) | |
{ | |
for (;;) | |
{ | |
if (ct.IsCancellationRequested) | |
ct.ThrowIfCancellationRequested(); | |
} | |
} | |
public override Task<T> Invoke<T>(string method, params object[] args) | |
{ | |
for (;;) | |
{ | |
if (ct.IsCancellationRequested) | |
ct.ThrowIfCancellationRequested(); | |
} | |
} | |
public override void Pause() | |
{ | |
throw new InvalidOperationException("already stopped"); | |
} | |
public override void Resume() | |
{ | |
throw new InvalidOperationException("already stopped"); | |
} | |
public override void Stop() | |
{ | |
throw new InvalidOperationException("already stopped"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment