如何在对象最后一个属性赋值完成时触发事件,避免重复计算?
解决方案
以下是适配不同业务场景的可落地实现方案:
方案1:批量修改开关模式(优先推荐,性能最优)
适用于可以明确知道批量修改起止时机的场景,完全手动控制计算触发时机,无多余性能损耗:
实现代码
public class Model { private bool _isUpdating; private int _blocks; private int _layers; private Color _color; public int Blocks { get => _blocks; set { _blocks = value; TryTriggerCompute(); } } public int Layers { get => _layers; set { _layers = value; TryTriggerCompute(); } } public Color Color { get => _color; set { _color = value; TryTriggerCompute(); } } // 开启批量修改模式,期间属性变更不会触发计算 public void BeginUpdate() => _isUpdating = true; // 结束批量修改,立即执行一次计算 public void EndUpdate() { _isUpdating = false; Compute(); // 如果需要兼容INotifyPropertyChanged做UI通知,也可以在这里统一触发所有属性变更通知,避免多次UI刷新 } private void TryTriggerCompute() { if (!_isUpdating) Compute(); } // 替换为你自己的计算逻辑 private void Compute() { // 计算业务代码 } }
调用示例
Model model = new Model(); model.BeginUpdate(); model.Blocks = 2; model.Layers = 3; ModelManager manager = new ModelManager(); manager.Models.Add(model); model.Color = Color.Blue; model.EndUpdate(); // 所有属性修改完成后,仅触发一次计算
方案2:防抖延迟触发模式
适用于无法预判批量修改起止时机的场景,通过短时间内屏蔽重复触发实现自动合并计算:
实现代码
public class Model { private readonly System.Timers.Timer _computeTimer; private int _blocks; private int _layers; private Color _color; public Model() { // 间隔可根据业务场景调整,一般设置为10-100ms即可覆盖连续赋值的场景 _computeTimer = new System.Timers.Timer(50); _computeTimer.AutoReset = false; _computeTimer.Elapsed += (s, e) => Compute(); } public int Blocks { get => _blocks; set { _blocks = value; ResetTimer(); } } public int Layers { get => _layers; set { _layers = value; ResetTimer(); } } public Color Color { get => _color; set { _color = value; ResetTimer(); } } // 每次属性变更重置计时器,只要连续修改的间隔小于阈值就只会触发一次计算 private void ResetTimer() { _computeTimer.Stop(); _computeTimer.Start(); } // 替换为你自己的计算逻辑 private void Compute() { // 计算业务代码 } }
方案3:链式修改提交模式
如果偏好更简洁的调用方式,可以实现链式API,最后统一提交触发计算:
实现代码
public class Model { public int Blocks { get; set; } public int Layers { get; set; } public Color Color { get; set; } public Model SetBlocks(int value) { Blocks = value; return this; } public Model SetLayers(int value) { Layers = value; return this; } public Model SetColor(Color value) { Color = value; return this; } // 提交修改时触发计算 public void Commit() { Compute(); } // 替换为你自己的计算逻辑 private void Compute() { // 计算业务代码 } }
调用示例
Model model = new Model() .SetBlocks(2) .SetColor(Color.Blue) .SetLayers(3); model.Commit(); // 仅触发一次计算
内容的提问来源于stack exchange,提问作者Jaime
相关产品推荐
相关产品推荐

