Created
April 14, 2017 22:10
-
-
Save JKamsker/d0c4e5838c6f29b6b0664fc799d5061f to your computer and use it in GitHub Desktop.
Watches constantly on the result of a func and executes an action if true
This file contains hidden or 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
internal class BwHelper | |
{ | |
public object SessObj { get; set; } | |
public Func<object, bool> CheckingAlg { get; set; } | |
public Action<bool, object> StatusChange { get; set; } | |
public bool doCallbackOn { get; set; } | |
public bool lastResult { get; set; } | |
public double NextCheck { get; set; } | |
public double Interval { get; set; } | |
} | |
internal class BoolWatcher | |
{ | |
public static Stopwatch SW { get => GetBoolWatcher().sw; } | |
private Stopwatch sw = Stopwatch.StartNew(); | |
private List<BwHelper> _internalTickList = new List<BwHelper>(); | |
private static BoolWatcher _BW; | |
private AutoResetEvent _ae = new AutoResetEvent(false); | |
private bool KillMe { get => _killMeSwitch; set { _killMeSwitch = value; _ae.Set(); } } | |
private bool _killMeSwitch; | |
private BoolWatcher() | |
{ | |
Thread th = new Thread(ThreadWork) | |
{ | |
IsBackground = true, | |
}; | |
th.Start(); | |
} | |
public static BoolWatcher GetBoolWatcher() | |
{ | |
if (_BW == null) | |
{ | |
_BW = new BoolWatcher(); | |
} | |
return _BW; | |
} | |
public int AddWatcher<T>(T SessionObject, Func<T, bool> CheckingAlgorithm, Action<bool, T> StatusChangeCallBack, double Interval, bool callBackOn) //;where T : class, new() | |
{ | |
int returnVal = -1; | |
lock (_internalTickList) | |
{ | |
if (typeof(T) is object || SessionObject is object) | |
{ | |
var AddVar = SessionObject as object; | |
_internalTickList.Add(new BwHelper() | |
{ | |
SessObj = SessionObject, | |
CheckingAlg = a => (CheckingAlgorithm((T)a)), | |
StatusChange = (a, b) => StatusChangeCallBack(a, (T)b), | |
doCallbackOn = callBackOn, | |
lastResult = !callBackOn | |
}); | |
returnVal = _internalTickList.Count - 1; | |
_ae.Set(); | |
} | |
} | |
return returnVal; | |
} | |
public void RemoveWatcher(int JobID) | |
{ | |
lock (_internalTickList) | |
{ | |
_internalTickList[JobID] = null; | |
} | |
} | |
public void RemoveWatcher(object Job) | |
{ | |
lock (_internalTickList) | |
{ | |
var ids = _internalTickList.Select((a, i) => a != null && a.SessObj == Job ? i : -1).Where(m => m != -1).ToArray(); | |
for (int i = 0; i < ids.Length; i++) | |
{ | |
_internalTickList[ids[i]] = null; | |
} | |
} | |
} | |
private void ThreadWork() | |
{ | |
int rTw = 0; | |
while (!KillMe) | |
{ | |
var ElapsedTime = sw.Elapsed.TotalMilliseconds; | |
var tlQuery = _internalTickList.Where(m => m != null); | |
int? ToWait = int.MaxValue; | |
lock (_internalTickList) | |
{ | |
if (tlQuery.Any()) | |
{ | |
ToWait = (int)(tlQuery.Min(m => m.NextCheck) - ElapsedTime); | |
} | |
else | |
{ | |
ToWait = null; | |
} | |
} | |
if (ToWait == null) | |
{ | |
_ae.WaitOne(); | |
} | |
else | |
{ | |
rTw = (int)ToWait; | |
if (rTw > 0) | |
{ | |
_ae.WaitOne(rTw); | |
} | |
} | |
if (KillMe) | |
return; | |
ElapsedTime = sw.Elapsed.TotalMilliseconds; | |
lock (_internalTickList) | |
{ | |
var ToExec = tlQuery.Where(m => m.NextCheck - ElapsedTime <= 2).ToArray(); | |
for (int i = 0; i < ToExec.Length; i++) | |
{ | |
var item = ToExec[i]; | |
var result = item.CheckingAlg(item.SessObj); | |
if (result != item.lastResult && result == item.doCallbackOn) | |
{ | |
item.lastResult = result; | |
item.StatusChange(result, item.SessObj); | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sample usage:
bw.AddWatcher(explorer, a => a.Busy == false, (a, b) =>
{
Console.WriteLine("UnBusy " + BoolWatcher.SW.Elapsed.TotalMilliseconds);
try
{
//It could be that its busy
if (b != null && !b.Busy)
{
BoolWatcher.GetBoolWatcher().RemoveWatcher(b);
onFoundNotBusy?.Invoke(b);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}, 1, true);