using System; using System.Collections.Generic; namespace XGame.Framework.Asyncs { public class AsyncGroup : AsyncAwaitable, IAsyncGroup, IDisposable, IAsyncListener where TAwaiter : IAwaiter, new() { protected HashSet elements; /// /// 是否不包含任务子异步,一般地如果为空则异步组就没什么价值 /// public bool Empty { get; private set; } = true; private bool bEnded = false; /// /// 执行中的任务子异步数量,用于计算Progress /// private int asyncCount = 0; public override float Progress { get { if (IsCompleted || elements == null || asyncCount <= 0) return base.Progress; float progress = 0; int count = elements.Count; foreach (var it in elements) { progress += it.Progress; } if (asyncCount >= count) { return (progress + asyncCount - count) / asyncCount; } return progress / count; } protected set => base.Progress = value; } public void AddAsync(IAsync ele) { if (ele == null || ele.IsCompleted) return; Empty = false; if (elements == null) { elements = new HashSet(); } if (elements.Add(ele)) { ele.On(this, 100); asyncCount++; } } public void RemoveAsync(IAsync ele) { if (elements == null) return; if (elements.Remove(ele)) { ele.RemoveOn(this); asyncCount--; } } public void OnAsyncCompleted(IAsync aAsync) { if (aAsync.Exception != null) { if (Exception == null) { Exception = new AsyncGroupException(); } (Exception as AsyncGroupException).AddException(aAsync.Exception); } elements?.Remove(aAsync); Check(); } /// /// 避免在添加过程中出现异步已经完成的情况! /// 需要确定一个时机表示AsyncGroup已经添加完子元素 /// public void End() { if (bEnded) return; bEnded = true; Check(); } private void Check() { if (!bEnded) return; if (elements == null || elements.Count == 0) { asyncCount = 0; Completed(); } } protected override void OnRemoveAll() { if (elements != null) { foreach (var element in elements) { element?.RemoveAll(); } elements.Clear(); } } public void Dispose() { if (Empty && !IsCompleted) { Completed(); } } } public class AsyncGroup : AsyncGroup { } }