如何在C#或类似框架中按顺序运行事件
本文关键字:顺序 运行 事件 框架 | 更新日期: 2023-09-27 17:58:29
如何取消/调整与另一线程中的同一事件并行执行的事件。
例如,在文本框中,每次我们输入字符时,如果定义了文本更改事件,就会触发事件。但在输入第一个字符后,事件(让我们称之为first event)会花费大量时间(因为会有更多的字符串与单个字符匹配),并执行一些操作,如更改标题标签的内容。在输入第二个字符后,引发并行运行的新事件所花费的时间更少。所以现在,在输入第二个字符后激发的第二个事件执行得很快,并返回第一个,第一个事件最后执行,因此,第一个活动的结果将最终打印在标签上,而不是第二个。
有没有更好的方法可以在开始第二个事件之前取消第一个事件。我想到的一件事是在全局列表变量中注册线程,并在开始执行之前杀死所有未死的线程。这行得通吗??任何更好的方法来处理这种情况。
附言:我知道搜索可以在空间或进入后启动,以解决这个特定的问题。但我想你已经注意到我的要点了
我最喜欢处理这个确切问题的库是Rx.Net
和TPL
。这种行为可以很容易地通过使用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.FromAsync
和Observable.Switch
。
每次我们在textBox中发生更改时,我们都会触发一个事件。这是由.Throttle
过滤的(正如您所期望的)。聪明的一点是,我们使用Observable.FromAsync
在DoSearchTaskAsync
上创建一个新的事件源。在这一点上,我们有一个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