diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs index 5d1bc0c..2f42487 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs @@ -107,6 +107,11 @@ namespace JoyD.Windows.CS { get { + // 读取操作也需要线程安全检查 + if (this.InvokeRequired) + { + return (Image)this.Invoke(new Func(() => mRealTimeImage)); + } return mRealTimeImage; } set @@ -116,38 +121,57 @@ namespace JoyD.Windows.CS { try { - this.BeginInvoke(new Action((img) => RealTimeImage = img), value); + // 使用Action委托设置值,避免闭包问题 + this.BeginInvoke(new Action(SetRealTimeImageInternal), value); } catch (ObjectDisposedException) { - // 控件已释放,释放传入的图像 + // 控件已释放,释放传入的图像资源 value?.Dispose(); } return; } - // 防止重复设置相同的图像 - if (mRealTimeImage == value) - return; - - // 检查是否在有效状态下操作 - if (this.IsDisposed || this.Disposing) - { - // 如果窗口已关闭或正在关闭,释放传入的图像 - value?.Dispose(); - return; - } - - // 释放旧图像 - if (mRealTimeImage != null && mRealTimeImage != value) - { - try { mRealTimeImage.Dispose(); } catch { } - } - - // 只设置mRealTimeImage,不直接更新UI - // UI更新将由定时器的Timer_Tick事件处理 - mRealTimeImage = value; + // 在UI线程上直接调用内部方法 + SetRealTimeImageInternal(value); } } + + /// + /// 内部方法,在UI线程上安全地设置实时图像 + /// + /// 要设置的新图像 + private void SetRealTimeImageInternal(Image value) + { + // 防止重复设置相同的图像 + if (mRealTimeImage == value) + return; + + // 检查是否在有效状态下操作 + if (this.IsDisposed || this.Disposing) + { + // 如果窗口已关闭或正在关闭,释放传入的图像 + value?.Dispose(); + return; + } + + // 释放旧图像资源 + if (mRealTimeImage != null && mRealTimeImage != value) + { + try + { + mRealTimeImage.Dispose(); + } + catch (Exception ex) + { + // 记录异常但不中断流程 + System.Diagnostics.Debug.WriteLine($"释放旧图像资源失败: {ex.Message}"); + } + } + + // 只设置mRealTimeImage,不直接更新UI + // UI更新将由定时器的Timer_Tick事件处理 + mRealTimeImage = value; + } } }