gpt4 book ai didi

c# - 从事件处理程序中使用 yield

转载 作者:行者123 更新时间:2023-11-30 19:49:51 24 4
gpt4 key购买 nike

我有一个方法 Foo.LongRunningMethod(),它执行一些可能会持续很长时间的非常复杂的处理。一路上,它会在遇到特定条件时触发 Foo.InterestingEvent。我希望能够公开这些事件的枚举,并且我希望能够在 LongRunningMethod 实际完成之前开始迭代。换句话说,我想要的是这样的:

public IEnumerable<InterestingObject> GetInterestingObjects()
{
foo.InterestingEvent += (obj) => { yield return obj; }
foo.LongRunningMethod();

yield break;
}

但这行不通,但是,出于合理的原因,您不能从匿名方法中 yield 返回(并且因为使用 yield 的方法不能返回 void,我们的事件处理程序就是这样做的)。还有另一个成语可以让我完成这个吗?或者这只是个坏主意?

最佳答案

您希望能够订阅来自 LongRunningMethod 的事件流并且,当事件发生时,从 IEnumerable 中产生另一个值?您可能会发现 .NET Reactive Extensions 很有用:http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx

响应式扩展给你 IObservable ,这实际上是一个只推 IEnumerable .您可以创建一个 IObservable包装事件(例如您的 InterestingEvent )并从那里对其进行可枚举式处理(例如产生对象流)。

Edit: "is there an idiom that allows me to accomplish this" other than adopting a new library from Microsoft? What you're doing is turning a push sequence (occurrences of an event) into a pull one (calls into IEnumerable).

The pulls and pushes probably aren't going to be coordinated, so you'll need somewhere to buffer new values that were pushed before a pull was made. The most straightforward way might be to adopt a producer-consumer arrangement: push those into a List<T> that's consumed by the caller of GetInterestingObjects.

Depending on how the events are raised, you might need to put the producer and consumer on separate threads. (All of this is what the reactive extensions end up doing, when you ask it to convert between an IObservable and an IEnumerable.)

关于c# - 从事件处理程序中使用 yield,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3260401/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com