Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#或类似框架中按顺序运行事件_C#_Multithreading_Events - Fatal编程技术网

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

如何在C#或类似框架中按顺序运行事件,c#,multithreading,events,C#,Multithreading,Events,如何取消/调整与另一个线程中的同一事件并行执行的事件 例如,在文本框中,每次输入字符时,如果定义了文本更改事件,则会触发事件。但是在输入第一个字符之后,事件(让我们称为第一个事件)需要很多时间(因为将有更多字符串与单个字符匹配),并执行一些操作,如更改标题标签的内容。输入第二个字符后,引发并行运行的新事件花费的时间更少。现在,在输入第二个字符后触发的第二个事件执行得很快,返回第一个,第一个事件最后执行,因此,第一个事件的结果将最终打印在标签上,而不是第二个 是否有更好的方法在开始第二个事件之前取

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

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

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


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

NET
Task
API内置了取消的概念。有关示例和更多信息的链接,请参见本页

我最喜欢的处理这个确切问题的库是
Rx.Net
TPL
。使用
Observable.fromsync

一些代码

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
                              });
请注意,没有必要显式键入任何此类内容…我这样做只是为了清楚起见,但我很可能键入了一两个类名

编辑

搜索方法将是
任务DoSearchTaskAsync(string,TaskCancellationToken)
的方法体

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

每次我们在文本框中进行更改时,我们都会触发一个事件。这是由
.Throttle
过滤的(如您所料)。聪明的一点是,我们随后使用
Observable.fromsync
DoSearchTaskAsync
上创建一个新的事件源。在这一点上,我们有一个
IObservable
,或者用另一种方式,一个eventsource的eventsource。切换意味着我们只需要outter eventsource中最近发送的eventsource的结果,并终止(处置)先前eventsource的订阅

当我们订阅新的
任务时,处理以前的
可见.fromsync
的行为将导致
任务取消令牌
取消,并防止其结果冒泡

所有这些都是非常聪明的东西,我只是最近才发现这个令人敬畏的模式(如果我可以的话,我会相信作者)


至于可观察的
。FromEventPattern
这是非常不幸的,从C#5开始,没有一流的事件处理程序,所以我们传入一个lambda用于订阅,一个lambda用于取消订阅。

我将研究如何操作事件流,与任务并行库一起…由于UI是单线程,因此事件始终按其自身顺序排列。@FelicePollano,但不一定是由事件启动的回调的结果。例如,如果用户键入“abc”,但您的客户端缓存了“abc”而不是“ab”的搜索结果,则UI可以使用“abc”的结果进行更新,然后是“ab”的结果。不太理想。如果不是太麻烦的话,你能给我解释一下代码吗??我对这东西有点陌生。提前谢谢。。我要找的东西是,1。在哪里绑定此事件??2.我的搜索操作方法在哪里被调用?(DoSearchTaskAsync???)3。它如何取消以前调用的事件??它需要参考这些方法,对吗??提前谢谢我刚看到你的编辑。。。刷新后:)谢谢:)@sriharshaKB我确实编辑了我的答案。这是我能做的最好的了。不幸的是,在理解我所写的解释之前,您需要在Rx.Net中有一个良好的基础。我想到了这一点。但我刚才提到了线程解决方案,因为两者都是相似的。嗯,我不完全知道。但在某种程度上,我们是在用自己的双手处理这个问题。还有其他解决方案吗??而且必须以某种方式调用内置的取消。然后我们可以将它绑定到一个变量,如果它为false,则停止执行。在这种情况下,我们可以将任务绑定到该变量。当下一个字符出现时,事件激发,变量将设置为false触发所有任务的结束。。然后,我们稍后再次将其设置为true,并再次将新任务绑定到该变量。听起来像科幻小说??)