mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-25 04:59:01 +08:00
refactor(coroutine): 优化协程调度器中的暂停计数统计
- 引入 _pausedCount 字段直接跟踪暂停协程数量 - 将统计信息中的 ActiveCount 和 PausedCount 改为线程安全的原子操作 - 在暂停和恢复协程时直接更新 _pausedCount 计数 - 修复 KillGroup 方法中的并发修改异常问题 - 重置统计信息时使用原子操作清零计数字段
This commit is contained in:
parent
06114db8bd
commit
74f27ddfd5
@ -27,6 +27,7 @@ public sealed class CoroutineScheduler(
|
|||||||
private readonly ITimeSource _timeSource = timeSource ?? throw new ArgumentNullException(nameof(timeSource));
|
private readonly ITimeSource _timeSource = timeSource ?? throw new ArgumentNullException(nameof(timeSource));
|
||||||
private readonly Dictionary<CoroutineHandle, HashSet<CoroutineHandle>> _waiting = new();
|
private readonly Dictionary<CoroutineHandle, HashSet<CoroutineHandle>> _waiting = new();
|
||||||
private int _nextSlot;
|
private int _nextSlot;
|
||||||
|
private int _pausedCount;
|
||||||
|
|
||||||
private CoroutineSlot?[] _slots = new CoroutineSlot?[initialCapacity];
|
private CoroutineSlot?[] _slots = new CoroutineSlot?[initialCapacity];
|
||||||
|
|
||||||
@ -133,7 +134,7 @@ public sealed class CoroutineScheduler(
|
|||||||
if (_statistics != null)
|
if (_statistics != null)
|
||||||
{
|
{
|
||||||
_statistics.ActiveCount = ActiveCoroutineCount;
|
_statistics.ActiveCount = ActiveCoroutineCount;
|
||||||
_statistics.PausedCount = _metadata.Count(m => m.Value.State == CoroutineState.Paused);
|
_statistics.PausedCount = _pausedCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按优先级排序槽位索引(高优先级优先执行)
|
// 按优先级排序槽位索引(高优先级优先执行)
|
||||||
@ -264,6 +265,7 @@ public sealed class CoroutineScheduler(
|
|||||||
|
|
||||||
slot.State = CoroutineState.Paused;
|
slot.State = CoroutineState.Paused;
|
||||||
meta.State = CoroutineState.Paused;
|
meta.State = CoroutineState.Paused;
|
||||||
|
_pausedCount++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,6 +285,7 @@ public sealed class CoroutineScheduler(
|
|||||||
|
|
||||||
slot.State = CoroutineState.Running;
|
slot.State = CoroutineState.Running;
|
||||||
meta.State = CoroutineState.Running;
|
meta.State = CoroutineState.Running;
|
||||||
|
_pausedCount--;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,7 +343,8 @@ public sealed class CoroutineScheduler(
|
|||||||
if (!_grouped.TryGetValue(group, out var handles))
|
if (!_grouped.TryGetValue(group, out var handles))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return handles.Count(Kill);
|
var copy = handles.ToArray();
|
||||||
|
return copy.Count(Kill);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -409,6 +413,7 @@ public sealed class CoroutineScheduler(
|
|||||||
|
|
||||||
_nextSlot = 0;
|
_nextSlot = 0;
|
||||||
ActiveCoroutineCount = 0;
|
ActiveCoroutineCount = 0;
|
||||||
|
_pausedCount = 0;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,9 @@ internal sealed class CoroutineStatistics : ICoroutineStatistics
|
|||||||
private readonly Dictionary<CoroutinePriority, int> _countByPriority = new();
|
private readonly Dictionary<CoroutinePriority, int> _countByPriority = new();
|
||||||
private readonly Dictionary<string, int> _countByTag = new();
|
private readonly Dictionary<string, int> _countByTag = new();
|
||||||
private readonly object _lock = new();
|
private readonly object _lock = new();
|
||||||
|
private int _activeCount;
|
||||||
private double _maxExecutionTimeMs;
|
private double _maxExecutionTimeMs;
|
||||||
|
private int _pausedCount;
|
||||||
private long _totalCompleted;
|
private long _totalCompleted;
|
||||||
private long _totalExecutionTimeMs;
|
private long _totalExecutionTimeMs;
|
||||||
private long _totalFailed;
|
private long _totalFailed;
|
||||||
@ -28,10 +30,18 @@ internal sealed class CoroutineStatistics : ICoroutineStatistics
|
|||||||
public long TotalFailed => Interlocked.Read(ref _totalFailed);
|
public long TotalFailed => Interlocked.Read(ref _totalFailed);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int ActiveCount { get; set; }
|
public int ActiveCount
|
||||||
|
{
|
||||||
|
get => Interlocked.CompareExchange(ref _activeCount, 0, 0);
|
||||||
|
set => Interlocked.Exchange(ref _activeCount, value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int PausedCount { get; set; }
|
public int PausedCount
|
||||||
|
{
|
||||||
|
get => Interlocked.CompareExchange(ref _pausedCount, 0, 0);
|
||||||
|
set => Interlocked.Exchange(ref _pausedCount, value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public double AverageExecutionTimeMs
|
public double AverageExecutionTimeMs
|
||||||
@ -84,14 +94,14 @@ internal sealed class CoroutineStatistics : ICoroutineStatistics
|
|||||||
Interlocked.Exchange(ref _totalCompleted, 0);
|
Interlocked.Exchange(ref _totalCompleted, 0);
|
||||||
Interlocked.Exchange(ref _totalFailed, 0);
|
Interlocked.Exchange(ref _totalFailed, 0);
|
||||||
Interlocked.Exchange(ref _totalExecutionTimeMs, 0);
|
Interlocked.Exchange(ref _totalExecutionTimeMs, 0);
|
||||||
|
Interlocked.Exchange(ref _activeCount, 0);
|
||||||
|
Interlocked.Exchange(ref _pausedCount, 0);
|
||||||
|
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
_maxExecutionTimeMs = 0;
|
_maxExecutionTimeMs = 0;
|
||||||
_countByPriority.Clear();
|
_countByPriority.Clear();
|
||||||
_countByTag.Clear();
|
_countByTag.Clear();
|
||||||
ActiveCount = 0;
|
|
||||||
PausedCount = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user