如何在C#或类似框架中按顺序运行事件

本文关键字:顺序 运行 事件 框架 | 更新日期: 2023-09-27 17:58:29

如何取消/调整与另一线程中的同一事件并行执行的事件。

例如,在文本框中,每次我们输入字符时,如果定义了文本更改事件,就会触发事件。但在输入第一个字符后,事件(让我们称之为first event)会花费大量时间(因为会有更多的字符串与单个字符匹配),并执行一些操作,如更改标题标签的内容。在输入第二个字符后,引发并行运行的新事件所花费的时间更少。所以现在,在输入第二个字符后激发的第二个事件执行得很快,并返回第一个,第一个事件最后执行,因此,第一个活动的结果将最终打印在标签上,而不是第二个。

有没有更好的方法可以在开始第二个事件之前取消第一个事件。我想到的一件事是在全局列表变量中注册线程,并在开始执行之前杀死所有未死的线程。这行得通吗??任何更好的方法来处理这种情况。

附言:我知道搜索可以在空间或进入后启动,以解决这个特定的问题。但我想你已经注意到我的要点了

如何在C#或类似框架中按顺序运行事件

我最喜欢处理这个确切问题的库是Rx.NetTPL。这种行为可以很容易地通过使用Observable.FromAsync 将可取消任务与事件观察器相结合来实现

一些代码!

var textChanged = Observable.FromEventPattern(x => textBox.TextChanged += x, x => textBox.TextChanged -= x)
                        .Select(_ => textBox.Text);
IDisposable eventHandler = textChanged.Throttle(TimeSpan.FromMilliseconds(500))
                              .Select(text => Observable.FromAsync((TaskCancelationToken cancel) => DoSearchTaskAsync(text, cancel)))
                              .Switch()
                              .Subscrible(results =>
                              {
                                  //Update the UI
                              });

请注意,没有必要显式键入任何此类。。。我这么做只是为了清楚起见,但我很可能打错了一两个类名。。。

编辑

Search方法将是Task<TReturn> DoSearchTaskAsync(string, TaskCancellationToken)的方法主体。

神奇的酱汁来自Observable.FromAsyncObservable.Switch

每次我们在textBox中发生更改时,我们都会触发一个事件。这是由.Throttle过滤的(正如您所期望的)。聪明的一点是,我们使用Observable.FromAsyncDoSearchTaskAsync上创建一个新的事件源。在这一点上,我们有一个IObservable<IObservable<TResult>>,或者另一种说法,一个事件源的事件源。切换意味着我们只想要来自outter事件源的最近发送的事件源的结果,并终止(Dispose)以前事件源的订阅。

当我们订阅新的Task时,处理前一个Observable.FromAsync的行为将导致TaskCancellationToken取消,并防止其结果冒泡。

所有这些都是非常聪明的东西,我最近才发现这种令人惊叹的模式(如果可以的话,我会称赞作者)。

至于非常不幸的Observable.FromEventPattern,从C#5开始,没有第一类事件处理程序,所以我们传入了一个用于订阅的lambda和一个用于取消预订的lambda。

.NET Task API内置了取消的概念。有关示例和更多信息的链接,请参阅此页。http://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx