2

我有一个 foreach 循环,在其中更新对象的属性。这个属性有一个依赖项,我在 setter 中更新它。这似乎减慢了我的应用程序,因为依赖项需要一些时间,并且在 foreach 循环之后只需更新一次。

不建议在循环后调用依赖的更新,因为我的代码中很多其他地方都用到了setter。除此之外,对象应该负责更新它的依赖而不是调用函数。

为清楚起见的代码示例

//anywhere else in my other classes
private Foo[] objects;

public void UpdateFoo()
{
  //update propably hundrets of small objects
  foreach (Foo obj in objects)
  {
    obj.Property = 1;
  }
}

class Foo
{
  private int _property;
  public int Property 
  { 
    get { return _property; } 
    set
    {
      _property = value;

      //Update something anywhere else
      StaticBigFoo.Update();
    } }
}

class StaticBigFoo
{
  public static void Update()
  {
    //do something longer
  }
}

我想知道这个场景的最佳实践是什么?

  • 我可以使用a DependencyProperty,它是PropertyChanged-Callback,但是每次仍然会更新依赖项。
  • 我想过在 Dispatcher 中启动一些东西,DispatcherPriority.Background并为不同的代表过滤它(但是如何?)
  • 我可以使用一些事务逻辑,但我不知道在那里使用什么。我读了一些关于的东西TransactionScope,我可以用它来做这样的事情吗?
4

3 回答 3

1

只是一个思考的食物,属性主要用于以受控方式获取/设置字段的值。或者在您的情况下,多一英里,即更改通知。可以说,可以进行验证,延迟加载。但似乎你在二传手中做的比这多得多,我不是最佳实践。为什么是因为,我们可能会更频繁地访问属性,这会导致属性被评估,因此是底层逻辑。

于 2013-05-31T07:22:39.583 回答
1

您可以使用由多个 GUI 元素提供的定义BeginUpdate()和调用的部分。EndUpdate()我的意思是类似于以下内容:

class Foo
{
  private int _property;
  public int Property 
  { 
    get { return _property; } 
    set
    {
      _property = value;

      if(inUpdate)
        propertyChanged = true;
      else
        //Update something anywhere else
        StaticBigFoo.Update();
    } }

    static bool inUpdate = false;
    static bool propertyChanged;
    public static void BeginUpdate() { inUpdate = true; propertyChanged = false; }
    public static void EndUpdate() { inUpdate = false; if(propertyChanged) StaticBigFoo.Update(); }
}

接着

Foo.BeginUpdate();    
foreach (Foo obj in objects)
{
  obj.Property = 1;
}
Foo.EndUpdate();

这允许在需要时推迟更新。

于 2013-05-31T07:24:29.203 回答
1

我会让二传手保持干净,在他们身上只做字段分配和 PropertyChanged。然后听 PropertyChanged 并在那里做额外的事情(如果你愿意,可以在一个单独的线程中 - 为了简单起见,在这里使用任务);

class Foo
{
 //constructor
 public Foo()
 {
    PropertyChanged += (s,args) =>
    {
       switch(args.PropertyName)
       {
          case "Property" :
            Task.Factory.StartNew(() => { StaticBigFoo.Update();});
            break;
         ....

 public int Property
 { get ...
 {
   set  
   {
      if(_property == value) return;
      _property = value;
      RaisePropertyChanged(() => Property);
    ......
于 2013-05-31T16:38:00.820 回答