Skip to content

Instantly share code, notes, and snippets.

@pranavkm
Created December 8, 2016 22:49
Show Gist options
  • Save pranavkm/102bfef83da8f6a14fed5a762b89c034 to your computer and use it in GitHub Desktop.
Save pranavkm/102bfef83da8f6a14fed5a762b89c034 to your computer and use it in GitHub Desktop.
private readonly object _callbackLock = new object();
private List<CallbackState> _callbacks = new List<CallbackState>();
private bool _registeredCallbackProxy;
private bool _canBeChanged = true;
public IDisposable RegisterChangeCallback(Action<object> callback, object state)
{
if (!_canBeChanged)
{
return NullDispoable.Singleton;
}
var changeTokenState = new ChangeTokenState(callback, state);
Callbacks.Add(changeTokenState);
EnsureCallbacksRegistered();
return changeTokenState.CallbackDisposable;
}
private void EnsureCallbacksRegistered()
{
lock (_callbackLock)
{
if (_registeredCallbackProxy)
{
return;
}
for (var i = 0; i < _changeTokens.Count; i++)
{
_changeTokens[i].RegisterChangeCallback(OnChange, null);
}
}
}
private void OnChange(object state)
{
_canBeChanged = false;
lock (_callbackLock)
{
for (var i = 0; i < _callbacks.Count; i++)
{
var callbackState = _callbacks[i];
if (callbackState.Disposable.Disposed)
{
continue;
}
callbackState.Callback(callbackState.State);
}
}
}
private class CallbackDisposable : IDisposable
{
public bool Disposed { get; private set; }
public void Dispose()
{
Disposed = true;
}
}
private struct CallbackState
{
public CallbackState(Action<object> callback, object state, CallbackDisposable disposable)
{
}
public Action<object> Callback { get; }
public object State { get; }
public CallbackDisposable Disposable { get; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment