代码之家  ›  专栏  ›  技术社区  ›  Pure.Krome

对于此.NET事件,是否可以传入此IList实例?

  •  4
  • Pure.Krome  · 技术社区  · 14 年前

    我有以下代码:-

    while (....)
    {
        var foo = DoTheFooShakeShakeShake(..);
        foos.Add(foo); // foos is an IList<Foo>, btw and is new'd, above.
    
        if (foos.Count % 100 == 0)
        {
            var e = new CustomFooEventArgs { UserId = whatever, Foos = foos };
            OnFooPewPew(this, e);
            foos.Clear();
        }
    }
    
    // We still might have some foo's left over.. so send em off also.
    // Excuse the woeful var names, below.
    var e2 = new CustomFooEventArgs { UserId = whatever, Foos = foos };
    OnFooPewPew(this, e2);
    

    所以,我把所有的foo都抓了一段时间。每100个foo's我就会触发一个事件,将foo's的列表传递给订阅者。然后我清除这个foo列表。循环完成后,我会向订阅者发送所有剩余的foo。

    4 回复  |  直到 14 年前
        1
  •  5
  •   Anthony Pegram    14 年前

    忘记清除吧,事实上你正在改变列表,这会给订阅你的事件的对象带来巨大的破坏。 如果它们保留返回的列表 ,您将随时更改添加到列表中的数据 清除它。

    ,因为它们可以改变列表并影响您自己的进程。

    如果这不是你想要的行为(我不认为是这样),你甚至不想发送一个副本,而是一个 IEnumerable<Foo> ReadOnlyCollection<Foo>

        2
  •  2
  •   Thomas Levesque    14 年前

    但是,您应该避免传递列表本身,您应该传递一个副本。否则,事件订阅者可以保留对列表的引用,并以不可预知的方式处理它。。。

        3
  •  2
  •   Zach Johnson    14 年前

    假设您可以控制所有订阅服务器,并且只在一个线程上工作,是的,这很好。否则,如果您无法控制订阅者(谁知道他们会做什么?)或者使用多个线程处理已发送的集合,则应考虑发送该集合的副本。

        4
  •  1
  •   Community Dan Abramov    7 年前

    我更愿意这样做的评论,但没有声誉:-)

    Anthony's answer 在你无法控制接收者的情况下,是为了确保你分发的列表副本是一个 ReadOnlyCollection<Foo> List<Foo> CustomFooEventArgs Foos 作为不可变的接口,例如 IEnumerable<Foo> 一个特别胆小的接球手 福斯 列表<Foo>

    至于 Thomas' answer ,没有什么可以阻止事件接收器使用 BeginInvoke ,除非我遗漏了什么。

    IEnumerable<Foo> 在里面 自定义FooEventArgs 不过,事实是 只读集合<Foo> 使用的是IMHO的一个实现细节。