public struct ProgressInfo { public string Message; public int Current, Total; } async Task Foo(IProgress<ProgressInfo> progress, CancellationToken ct)
public static IEnumerable<object> Process<T>(this ICollection<T> collection, Action<T> action) { ProgressInfo info = new ProgressInfo() { Total = collection.Count }; foreach (var item in collection) { action(item); info.Current++; info.Message = string.Format("Processed {0:d} from {1:d}", info.Current, info.Total); yield return info; } yield break; }
IEnumerable<object> Foo() { yield break; } IEnumerable<object> Bar() { yield break; } IEnumerable<object> Baz() { foreach (var a in Foo()) yield return a; foreach (var b in Bar()) yield return b; yield break; }
IEnumerable<object> Baz() { yield return Foo(); yield return Bar(); yield break; }
public static IEnumerable<object> Flat(this IEnumerable<object> cot) { foreach (var a in cot) { var ea = a as IEnumerable<object>; if (ea==null) yield return a; else { foreach (var b in ea.Flat()) yield return b; } } yield break; }
public static void Execute(this IEnumerable<object> cot) { foreach (var a in cot.Flat()) { } }
public class ValueOf<T> { public T Value; } public static IEnumerable<object> Timeout(this IEnumerable<object> cot, TimeSpan duration, ValueOf<bool> timeout) { var limit = DateTimeOffset.Now+duration; foreach (var a in cot.Flat()) { if (DateTimeOffset.Now>limit) { timeout.Value = true; break; } yield return a; } yield break; }
public static IEnumerable<object> Rate(this IEnumerable<object> cot, double rate) { double summ = 0.001; foreach (var a in cot.Flat()) { summ += 1.0; while (summ>rate) { summ -= rate; yield return a; } } yield break; }
public static IEnumerable<object> Wait(Func<bool> condition) { while (!condition()) yield return null; yield break; }
public class TimerThread { bool _IsCancelled, _IsCompleted; DispatcherTimer Timer; IEnumerator<object> Enumerator; public event Action<ProgressInfo> Progress; public TimerThread(IEnumerable<object> cot, double interval) { Enumerator = cot.Flat().GetEnumerator(); Timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(interval) }; Timer.Tick += Timer_Tick; } void Timer_Tick(object sender, EventArgs ea) { if (!Enumerator.MoveNext()) { _IsCompleted = true; Timer.IsEnabled = false; } else if (Enumerator.Current is ProgressInfo) { if (Progress!=null) Progress((ProgressInfo)Enumerator.Current); } } public bool IsEnabled { get { return Timer.IsEnabled; } set { if (_IsCancelled || _IsCompleted) return; Timer.IsEnabled = value; } } public bool IsCancelled { get { return _IsCancelled; } set { if (!value) return; _IsCancelled = true; Timer.IsEnabled = false; } } public bool IsCompleted { get { return _IsCompleted; } } }
Source: https://habr.com/ru/post/315280/
All Articles