- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
如何使实现 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
。
首先,安装PropertyChanged.Fody ,可从 NuGet 获得。
当前实现 INofityPropertyChanged
的每个类都应该改为具有属性 [ImplementPropertyChanged]
。应删除手动实现。查看readme和 wiki了解更多信息。
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();
}
}
}
在某处设置 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/
我仍在学习整个任务概念和 TPL。根据我目前的理解,await 使用 SynchronizationContext 函数(如果存在)将任务分派(dispatch)到“某处”。另一方面,Task 类中的
感谢 Jeremy Miller 在 Functional Programming For Everyday .NET Development 中的出色工作,我有一个工作命令执行器,它可以做我想做的一
我使用 SynchronizationContext从 UI 线程上的后台线程调用方法。我读了this post它要求 Send 的差异和 Post .我明白答案并会调用Send每当我需要调用方法的结
我遇到了挂起等待的问题(描述 here )。在研究过程中,我发现调用 SetResult在我的 TaskCompletionSource实际上在调用 SetResult 的线程的上下文中调用等待继续(
public static void Init() { //var task = GetSource1(); //var task = GetSource2(); //var
在异步函数内部使用与外部不同的 SynchronizationContext 时,我的行为令人困惑。 我的大部分程序代码都使用自定义 SynchronizationContext,它只是将 SendO
我正在尝试了解 SynchronizationContext 和 friend 。如果我在例如开始时设置自定义同步上下文控制台应用程序。在什么情况下当前同步上下文将与我的异步操作一起流动?Task 和
我想了解更多关于 SynchronizationContext 的信息,所以我制作了这个简单的控制台应用程序: private static void Main() { var sc = ne
我不知道如何获取给定 Thread 的 SynchronizationContext: Thread uiThread = UIConfiguration.UIThread; Synchronizat
如何比较 SynchronizationContext?似乎同一个 Dispatcher 在使用 BeginInvoke 时可以创建不同的 SynchronizationContext。当我深入研究两
在Programming C#一书中,它有一些关于SynchronizationContext的示例代码。 : SynchronizationContext originalContext = Syn
对于 WinForms 和 WPF,我使用 SynchronizationContext 作为同步到 GUI 线程的方法。最近我遇到了旧式异步回调的问题: private void Button
我有以下代码: [TestMethod] public void StartWorkInFirstThread() { if (SynchronizationContext.Current =
SynchronizationContext 有一个名为 IsWaitNotificationRequired 的属性.出于其目的,docs有话要说: Determines if wait notif
说,我有以下代码: IPrincipal capturedPrincipal = Thread.CurrentPrincipal; myseq.AsParallel().Select(x => {
这是一个非常基本的问题,我想是的,但是我找不到任何明确的答案。 SynchronizationContext.Post()线程安全吗? 我有一个成员变量,它保存主线程的上下文,并且从多个线程中调用_c
SynchronizationContext.Current 在主线程上为 null,我很难弄清楚这一点。 static class Program { /// //
我正在创建 SynchronizationContext 的 STA 版本以用于 Windows Workflow 4.0。我想知道在发布回调时如何处理异常。 SynchronizationConte
简而言之,我已经实现了一个派生自 SynchronizationContext 的类,以便 GUI 应用程序可以轻松地使用在 GUI 线程以外的线程上引发的事件。我非常感谢对我的实现的评论。具体来说,
我有两个线程,一个是主线程,另一个是我创建的线程来做一些工作。我不明白当我从另一个线程调用 originalContext.Post(主线程的 SyncronizationContext)时会发生什么
我是一名优秀的程序员,十分优秀!