有了这个.NET事件,可以传入这个IList实例吗?

有了这个.NET事件,可以传入这个IList实例吗?,.net,events,list,collections,.net,Events,List,Collections,我有以下代码:- 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 = fo

我有以下代码:-

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);
while(…)
{
var foo=dothefooshakeshake(…);
foos.Add(foo);//foos是一个IList,顺便说一句,是新的,如上所述。
如果(foos.Count%100==0)
{
var e=new CustomFooEventArgs{UserId=where,Foos=Foos};
OnFooPewPew(本,e);
foos.Clear();
}
}
//我们可能还剩下一些食物。。所以也把他们送走。
//请原谅下面那些可悲的var名称。
var e2=newcustomfooEventArgs{UserId=where,Foos=Foos};
OnFooPewPew(本,e2);
因此,我在一段时间内获取所有foo/loop条件。然后,每隔100个foo's我就会触发一个事件,将foo's列表传递给订阅者。然后我清除这个foo列表。循环完成后,我会向订阅服务器发送剩余的foo


所以-如果我触发一个事件,其中包含foo的列表。。。然后我清除了那个列表。。这是否意味着订阅者可以得到现在为空的列表?我是否应该传递一份名单的副本。。。然后清除原始列表?

清除列表时,事件处理程序将已经执行(它们被同步调用),因此这不是问题


但是,您应该避免传递列表本身,您应该传递一份副本。否则,事件订阅服务器可以保留对列表的引用,并以不可预测的方式将其弄乱…

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

忘记清除,事实上,您正在改变列表,这将对订阅您的事件的对象造成严重破坏。如果它们保留返回的列表,则无论何时添加或清除该列表,您都将更改数据

你不仅可以搞乱订阅者,他们还可以搞乱你,因为他们可以改变列表,影响你自己的流程


如果这不是您想要的行为(我不认为是这样),那么您甚至不希望发送副本,而是希望发送
IEnumerable
ReadOnlyCollection
。因为即使你发送一份拷贝,如果你有多个订户,他们都会收到同一份拷贝,所以他们的突变仍然会对彼此造成严重破坏。

我更愿意用评论来做这件事,但没有声誉:-)

您无法控制接收者的偏执扩展是为了确保您分发的列表副本是一个
只读集合
(*)。如果您只是将列表复制为另一个
list
或其他可变集合,即使
CustomFooEventArgs
Foos
定义为一个不可变的接口,例如
IEnumerable
,一个特别卑鄙的接收者也可以将
Foos
转换为
list
,并对其进行变异

至于,使用
BeginInvoke
停止事件接收器生成异步任务没有任何好处,除非我遗漏了什么


(*)我可能会在
CustomFooEventArgs
中将其定义为
IEnumerable
,但是,使用
ReadOnlyCollection
这一事实是一个实现细节IMHO。

是否可以触发/处理异步事件?是的,如果使用BeginInvoke调用处理程序。但这是你控制的,不是订户