Closed Bian-Sh closed 1 month ago
这个dispatchAction列表设计意图是用于非unity线程往unity线程中插入需要操作unity相关api的代码用的 所以不应该出现执行dispatch中的action时出现修改dispatchaction list的行为,这种情况下我更倾向于抛出异常
每次dispatchaction执行时,复制一个列表的开销过大
那你用 ConcurrentQueue 吧,反正你这种写法就是错误的
private ConcurrentQueue<Action> m_dispatchActions = new ConcurrentQueue<Action>();
public void Dispatch(Action action)
{
m_dispatchActions.Enqueue(action);
}
private void LateUpdate()
{
if (layoutTask.Count > 0)
{
foreach (UIElement element in layoutTask)
{
if (element.Rect == null) continue;
if (element.TopParent == null) element.BeginLayout();
}
layoutTask.Clear();
Canvas.ForceUpdateCanvases();
}
while (m_dispatchActions.TryDequeue(out var action))
{
action.Invoke();
}
}
你还别说,我真有说错的地方,你这里没有用到lock,真可能不会死锁,但是这样还是危险的啊 毕竟可能存在不同线程同时操作 list 的情况
你看看这俩代码区别,为啥Unity要这么改呢? 首先,他有 lock ,你没有 其次,第二个版本中,他使用了中间列表转手了一下,你也没有 https://github.com/Unity-Technologies/UnityCsReference/blob/2018.2/Runtime/Export/UnitySynchronizationContext.cs https://github.com/Unity-Technologies/UnityCsReference/blob/2018.3/Runtime/Export/UnitySynchronizationContext.cs
https://github.com/AlienJack/AlienUICore/blame/66425c710fc5fee9206fb82e6f0e60da31fa2733/AlienUI/Runtime/Core/Engine.cs#L147