【发布时间】:2016-02-27 09:14:39
【问题描述】:
当类属性更改时,我需要更新 SQLite 数据库。这是一个糟糕的实现,它准确地展示了需要在更大范围内完成的工作:
internal class MyClass
{
private bool isFoo;
internal bool IsFoo
{
get { return isFoo; }
private set
{
isFoo = value;
UpdateDatabase(); // ← This method could take some time.
}
}
private void UpdateDatabase()
{
DatabaseClass.Update(this);
}
}
SO 用户 LukeH 在answer 中说:
如果两个线程同时访问 [a property],getter 将 短暂阻塞第二个线程,直到它返回对象到 第一个线程...
当前方向
我不想阻止对该属性的访问。如果我实现INotifyPropertyChanged,我的代码要么在保存数据的方式上不一致,要么将DatabaseClass 变成一堆乱七八糟的处理程序。这是我不愿意使用的方法:
public class MyClass
{
private bool isFoo;
internal bool IsFoo
{
get { return isFoo; }
private set
{
isFoo = value;
UpdateRequesting(); // Call delegate, similar to INotifyPropertyChanged
}
}
// Private event and delegate.
private delegate bool OnUpdateRequesting();
private event OnUpdateRequesting UpdateRequesting;
internal MyClass()
{
// Subscribe to private event inside of constructor.
UpdateRequesting += UpdateDatabase;
}
// Now, raised by event rather than called directly from set accessor.
private bool UpdateDatabase()
{
return DatabaseClass.Update(this);
}
}
使用私人活动感觉就像在拨打自己的电话号码。在不锁定属性的情况下调用 UpdateDatabase() 的正确方法是什么?
【问题讨论】:
-
当
IsFoo发生变化时,你会在UI线程中构建一个Sql命令,然后你可以在其他线程中执行。这样你就可以毫无问题地实现INotifyPropertyChanged -
@Sakura :实现
INotifyPropertyChanged与上面的代码几乎相同。只需将OnUpdateRequesting替换为OnPropertyChanged;但是,这将需要MyClass和PropertyChangedEventArgs的不必要实例。 -
你如何使用
UpdateRequesting();?您是调用函数来刷新 UI,还是为控件设置值? -
@Sakura :
get { } set { UpdateRequesting() } -
@Sakura :通常,属性会在最终用户单击按钮或更改设置时设置。
标签: c# wpf database multithreading accessor