/Reflection.cs |
@@ -115,8 +115,9 @@ |
/// </summary> |
/// <typeparam name="T">the enumeration type</typeparam> |
/// <param name="name">the description of a member</param> |
/// <param name="comparison">the string comparison to use</param> |
/// <returns>the value or the default of T if case no name attribute found</returns> |
public static T GetEnumValueFromName<T>(string name) |
public static T GetEnumValueFromName<T>(string name, StringComparison comparison = StringComparison.OrdinalIgnoreCase) |
{ |
var field = typeof(T).GetRuntimeFields().ToArray() |
.AsParallel().SelectMany(f => f.GetCustomAttributes( |
@@ -123,7 +124,7 @@ |
typeof(NameAttribute), false), ( |
f, a) => new {Field = f, Att = a}) |
.SingleOrDefault(a => Strings.StringEquals(((NameAttribute) a.Att) |
.Name, name, StringComparison.Ordinal)); |
.Name, name, comparison)); |
return field != null ? (T) field.Field.GetValue(Activator.CreateInstance<T>()) : default(T); |
} |
|
/Timers/Timer.cs |
@@ -12,21 +12,23 @@ |
{ |
public class Timer : IDisposable |
{ |
private readonly Action callback; |
private readonly Task CompletedTask = Task.FromResult(false); |
private Task Delay; |
private bool Disposed; |
private TimeSpan dueTime; |
private TimeSpan period; |
|
private CancellationTokenSource tokenSource; |
|
public Timer(Action callback, TimeSpan dueTime, TimeSpan period) |
public Timer() |
{ |
this.callback = callback; |
this.dueTime = dueTime; |
this.period = period; |
} |
|
Run(); |
public Timer(Action callback, TimeSpan dueTime, TimeSpan period) : this() |
{ |
Callback = callback; |
DueTime = dueTime; |
Period = period; |
|
Start(); |
} |
|
public Timer(Action callback, int dueTime, int period) |
@@ -48,8 +50,18 @@ |
{ |
} |
|
public Action Callback { set; get; } |
|
public TimeSpan DueTime { get; set; } = TimeSpan.Zero; |
|
public TimeSpan Period { get; set; } = TimeSpan.Zero; |
|
public void Dispose() |
{ |
// Stop the timer. |
Stop(); |
|
// Dispose the token. |
if (tokenSource != null) |
{ |
tokenSource.Cancel(); |
@@ -56,12 +68,18 @@ |
tokenSource.Dispose(); |
tokenSource = null; |
} |
|
// Set the disposed flag. |
Disposed = true; |
} |
|
private void Run() |
private void Start() |
{ |
// Cancel any previous timer. |
// Check if we have an installed callback and that there is at least a due time. |
if (Callback == null || DueTime.Equals(TimeSpan.Zero)) |
return; |
|
// Dispose the previous token source. |
if (tokenSource != null) |
{ |
tokenSource.Cancel(); |
@@ -73,21 +91,22 @@ |
tokenSource = new CancellationTokenSource(); |
|
Action tick = null; |
|
tick = () => |
{ |
Task.Run(() => callback(), tokenSource.Token); |
Task.Run(Callback, tokenSource.Token); |
if (Disposed) |
return; |
Delay = !period.Equals(0) ? Task.Delay(period, tokenSource.Token) : CompletedTask; |
if (Delay.IsCompleted) |
Delay = !Period.Equals(TimeSpan.Zero) ? Task.Delay(Period, tokenSource.Token) : CompletedTask; |
if (Disposed || Delay.IsCompleted) |
return; |
Delay.ContinueWith(t => tick(), tokenSource.Token); |
Delay.ContinueWith(o => tick(), tokenSource.Token); |
}; |
|
Delay = !dueTime.Equals(0) ? Task.Delay(dueTime, tokenSource.Token) : CompletedTask; |
if (Delay.IsCompleted) |
Delay = !DueTime.Equals(TimeSpan.Zero) ? Task.Delay(DueTime, tokenSource.Token) : CompletedTask; |
if (Disposed || Delay.IsCompleted) |
return; |
Delay.ContinueWith(t => tick(), tokenSource.Token); |
Delay.ContinueWith(o => tick(), tokenSource.Token); |
} |
|
public void Change(int dueTime, int period) |
@@ -102,10 +121,10 @@ |
|
public void Change(TimeSpan dueTime, TimeSpan period) |
{ |
this.dueTime = dueTime; |
this.period = period; |
DueTime = dueTime; |
Period = period; |
|
Run(); |
Start(); |
} |
|
public void Stop() |