.net 如何使用反应式扩展对事件流中与特定模式匹配的内容作出反应?
假设您希望在文本框中的字符流中的某个单词与某个模式匹配时做出反应,这可以使用Rx实现吗?因此,如果初始源如下所示:.net 如何使用反应式扩展对事件流中与特定模式匹配的内容作出反应?,.net,system.reactive,.net,System.reactive,假设您希望在文本框中的字符流中的某个单词与某个模式匹配时做出反应,这可以使用Rx实现吗?因此,如果初始源如下所示: var charStream = Observable. FromEventPattern<KeyPressEventArgs>(textBox, "KeyPress"); 然后,wordObservable的观察者可以过滤出与模式匹配的单词。然而,使用.NET中的旧式事件机制可以轻松实现上述功能,而且还没有考虑到某些文本可以在文本框中的任何位置复制,或者在已
var charStream = Observable.
FromEventPattern<KeyPressEventArgs>(textBox, "KeyPress");
然后,wordObservable
的观察者可以过滤出与模式匹配的单词。然而,使用.NET中的旧式事件机制可以轻松实现上述功能,而且还没有考虑到某些文本可以在文本框中的任何位置复制,或者在已编写的单词中间按enter键等
我的问题是,Rx是否不适合这种问题,或者Rx中是否有一些东西可以在这里应用(我确实意识到,除了使用Rx,还有其他解决方法,我只是想了解Rx的工作原理)?我相信可以使用,但我相信你从错误的角度看待这个问题 您正在将查看作为获取字符流的方式。这是不正确的,
KeyPress
事件的可观察性就是按键。是的,它们有时与文字中的字符相对应,但正如您所提到的,有些按键与文字中的字符无关,而是与其他操作有关
也就是说,您不应该订阅KeyPress
事件,而是订阅。然后,您应该返回与单词对应的字符串实例数组
换言之,与其以叠加的方式连续按键并试图找出框中的单词,不如将框中的整个文本作为观察对象,并将框中单词的变化作为观察对象:
var textChanges = Observable.
FromEventPattern<EventHandler>(textBox, "TextChanged");
// Create an observable that contains the splits.
IObservable<IList<string>> observableWordChanges = textChanges.Select(e => {
// Get the text.
string text = (e.Sender as TextBox).Text;
// The current word.
var word = new StringBuilder();
// The list of words.
IList<string> words = new List<string>();
// Parse.
foreach (char c in text)
{
if (!Char.IsWordSeparator(c))
word.Append(c);
else
{
// Add to the words.
words.Add(word.ToString());
// Clear the builder.
word.Clear();
}
}
// Return the words.
return words;
});
var textChanges=可观察。
FromEventPattern(textBox,“TextChanged”);
//创建包含拆分的可观察对象。
IObservable observewordchanges=textChanges.Select(e=>{
//获取文本。
字符串text=(e.Sender作为TextBox);
//当前单词。
var word=新的StringBuilder();
//单词表。
IList words=新列表();
//解析。
foreach(文本中的字符c)
{
if(!Char.IsWordSeparator(c))
追加(c);
其他的
{
//添加到单词中。
words.Add(word.ToString());
//清除生成器。
word.Clear();
}
}
//返回单词。
返回单词;
});
从这里,您可以将单词中的更改作为一个集合进行订阅,而不仅仅是文本框中的字符
诚然,它的计算强度更高一些,但另一种选择是捕获任何按键都可能具有的所有不同状态,而您可能无法获得所有正确的状态
这样,您每次都可以得到框中的单词,并且可以正确地与前面的单词进行比较
至于这样做是否有任何价值,而不仅仅是使用原始事件,我会说是的。使用反应式扩展的两大好处是:
- 用于处理事件流的逻辑封装
- 处理对同一事件流的多个订阅
在这个特定的示例中,您可以从这两个方面获益
您可以通过挂接TextChanged
事件来完成单词集解析,但是您必须在声明事件处理程序(在本例中为)的相同结构中存储某种状态。对于反应式扩展,这是不需要的(它包含在机柜中)
此外,如果您想在处理事件流时附加一些额外的行为,则必须在一个事件处理程序或多个事件处理程序中有两个调用。使用反应式扩展,由于更好地封装了状态,因此无论您选择什么时间(取决于您订阅的时间),都可以更容易地为同一事件添加多个事件流处理程序。我相信可以使用,但我相信您从错误的角度处理问题
您正在将查看作为获取字符流的方式。这是不正确的,KeyPress
事件的可观察性就是按键。是的,它们有时与文字中的字符相对应,但正如您所提到的,有些按键与文字中的字符无关,而是与其他操作有关
也就是说,您不应该订阅KeyPress
事件,而是订阅。然后,您应该返回与单词对应的字符串实例数组
换言之,与其以叠加的方式连续按键并试图找出框中的单词,不如将框中的整个文本作为观察对象,并将框中单词的变化作为观察对象:
var textChanges = Observable.
FromEventPattern<EventHandler>(textBox, "TextChanged");
// Create an observable that contains the splits.
IObservable<IList<string>> observableWordChanges = textChanges.Select(e => {
// Get the text.
string text = (e.Sender as TextBox).Text;
// The current word.
var word = new StringBuilder();
// The list of words.
IList<string> words = new List<string>();
// Parse.
foreach (char c in text)
{
if (!Char.IsWordSeparator(c))
word.Append(c);
else
{
// Add to the words.
words.Add(word.ToString());
// Clear the builder.
word.Clear();
}
}
// Return the words.
return words;
});
var textChanges=可观察。
FromEventPattern(textBox,“TextChanged”);
//创建包含拆分的可观察对象。
IObservable observewordchanges=textChanges.Select(e=>{
//获取文本。
字符串text=(e.Sender作为TextBox);
//当前单词。
var word=新的StringBuilder();
//单词表。
IList words=新列表();
//解析。
foreach(文本中的字符c)
{
if(!Char.IsWordSeparator(c))
追加(c);
其他的
{
//添加到单词中。
words.Add(word.ToString());
//清除生成器。
word.Clear();
}
}
//返回单词。
返回单词;
});
从这里,您可以将单词中的更改作为一个集合进行订阅,而不仅仅是文本框中的字符
当然,它的计算强度要高一点,但另一种选择是捕获任何按键都会具有的所有不同状态,而您可能无法将它们全部正确
Observable.FromEvent<EventArgs>(txt, "TextChanged")
.Select(e => ((TextBox)e.Sender).Text)
.SelectMany(t => t.Split(" ".ToCharArray()).Where(
a => !String.IsNullOrWhiteSpace(a)))