gpt4 book ai didi

c# - 如何在没有 SynchronizationContext 的情况下使用 INotifyPropertyChanged 实现线程安全?

转载 作者:太空宇宙 更新时间:2023-11-03 17:18:03 24 4
gpt4 key购买 nike

如何使实现 INotifyPropertyChanged 的​​对象保持线程安全?我不能使用 SynchronizationContext,因为我需要能够序列化该对象。

    protected void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
// What can I add here to make it thread-safe?
handler(this, new PropertyChangedEventArgs(propertyName));
}

最佳答案

所以...事实证明,如果您不介意依靠扩展在编译时为您生成一些代码,那么实际上有一种非常好的方法。无论如何,我都在使用 Fody/PropertyChanged,这使它成为一个非常容易的改变。这避免了在真正不了解 UI 的模型中引用 SynchronizationContext

  1. 首先,安装PropertyChanged.Fody ,可从 NuGet 获得。

  2. 当前实现 INofityPropertyChanged 的每个类都应该改为具有属性 [ImplementPropertyChanged]。应删除手动实现。查看readmewiki了解更多信息。

  3. A PropertyChangedNotificationInterceptor需要实现。他们在 wiki 中提供了 WPF 示例;我对 WinForms 项目的实现:

    public static class PropertyChangedNotificationInterceptor
    {
    public static SynchronizationContext UIContext { get; set; }

    public static void Intercept(object target, Action onPropertyChangedAction, string propertyName)
    {
    if (UIContext != null)
    {
    UIContext.Post(_ =>
    {
    onPropertyChangedAction();
    }, null);
    }
    else
    {
    onPropertyChangedAction();
    }
    }
    }
  4. 在某处设置 PropertyChangedNotificationInterceptor.UIContext。您可以将 PropertyChangedNotificationInterceptor.UIContext = WindowsFormsSynchronizationContext.Current; 放在主窗体的构造函数中。

    Form constructor通过 Control constructor并且最终将创建 WindowsFormsSynchronizationContext(如果尚不存在)。因此,在这里捕获 .Current 是安全的。 (注意:这可能是一个实现细节,并且可能会在未来的 .NET 版本、不同的平台等中发生变化)

请记住,这仅在您只有一个同步上下文(一个 UI 线程)时才有效。如果您遇到多个 UI 线程的困惑情况, 需要对多个线程进行数据绑定(bind),这会变得更加复杂。所以请不要那样做。

感谢Simon Cropp感谢编写 PropertyChanged 并帮助我找到它的这个特殊功能。

关于c# - 如何在没有 SynchronizationContext 的情况下使用 INotifyPropertyChanged 实现线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10130183/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com