目前,我正在使用带有Scala(和JavaFX)的EventBus/PubSub架构/模式来实现一个简单的笔记组织应用程序(有点像Evernote客户端,带有一些添加的思维导图功能),我不得不说我真的很喜欢EventBus观察者模式.
以下是一些EventBus库:
https://code.google.com/p/guava-libraries/wiki/EventBusExplained
http://eventbus.org(目前似乎已经失效)这是我在实施中使用的那个.
http://greenrobot.github.io/EventBus/
以下是EventBus库的比较:http://codeblock.engio.net/37/
EventBus与发布 - 订阅模式相关.
但是!
最近,我参加了Coursera的Reactive课程并开始怀疑使用RXJava而不是EventBus是否会在单线程应用程序中简化事件处理代码?
我想问一下关于使用这两种技术(某种eventbus库谁编程的人的经验和某种形式的反应扩展(RX)):是很容易解决的事件处理使用RX复杂性比与事件总线架构给出没有必要使用多个线程?
我问这个,因为我已经在听到无功讲座Coursera是RX(即没有"回调地狱")导致更清洁的代码比使用观察者模式,但是我没有找到VS EventBus架构之间的任何比较RXJava.所以很明显,EventBus和RXJava都比观察者模式更好,但 在代码清晰度和可维护性方面,它在单线程应用程序中更好?
如果我理解正确的话,RXJava的主要卖点是,如果存在阻塞操作(例如,等待来自服务器的响应),它可用于生成响应式应用程序.
但我根本不关心异步性,我所关心的只是在单线程应用程序中保持代码清洁,解开并易于推理.
在这种情况下,使用RXJava比使用EventBus更好吗?
我认为EventBus将是一个更简单,更清晰的解决方案,我认为没有任何理由可以将RXJava用于单线程应用程序,而采用简单的EventBus架构.
但我可能错了!
如果我错了,请纠正我,并解释为什么RXJava在单线程应用程序中没有执行阻塞操作的情况下比简单的EventBus更好.
event-handling reactive-programming system.reactive event-bus rx-java
使用Reactive Extensions,我想忽略来自我的Subscribe方法运行时发生的事件流的消息.也就是说,处理消息的时间有时比消息之间的时间长,所以我想删除没有时间处理的消息.
但是,当我的Subscribe方法完成时,如果有任何消息确实通过,我想处理最后一个消息.所以我总是处理最新消息.
所以,如果我有一些代码可以:
messages.OnNext(100);
messages.OnNext(1);
messages.OnNext(2);
Run Code Online (Sandbox Code Playgroud)
如果我们假设'100'需要很长时间来处理.然后我希望在'100'完成时处理'2'.应该忽略'1',因为它仍然被'2'取代,而'100'仍在处理中.
这是我想要使用后台任务的结果示例 Latest()
var messages = Observable.Interval(TimeSpan.FromMilliseconds(100));
Task.Factory.StartNew(() =>
{
foreach(var n in messages.Latest())
{
Thread.Sleep(TimeSpan.FromMilliseconds(250));
Console.WriteLine(n);
}
});
Run Code Online (Sandbox Code Playgroud)
但是,Latest()是一个阻塞调用,我宁愿不让一个线程等待下一个这样的值(消息之间有时会有很长的间隙).
我也可以使用BroadcastBlock来自TPL Dataflow的结果得到我想要的结果,如下所示:
var buffer = new BroadcastBlock<long>(n => n);
Observable.Interval(TimeSpan.FromMilliseconds(100)).Subscribe(n => buffer.Post(n));
buffer.AsObservable()
.Subscribe(n =>
{
Thread.Sleep(TimeSpan.FromMilliseconds(250));
Console.WriteLine(n);
});
Run Code Online (Sandbox Code Playgroud)
但感觉它应该可以直接在Rx中使用.这是最好的方法吗?
我正在WinForms中学习Rx,并拥有以下代码:
// Create an observable from key presses, grouped by the key pressed
var groupedKeyPresses = Observable.FromEventPattern<KeyPressEventArgs>(this, "KeyPress")
.Select(k => k.EventArgs.KeyChar)
.GroupBy(k => k);
// Increment key counter and update user's display
groupedKeyPresses.Subscribe(keyPressGroup =>
{
var numPresses = 0;
keyPressGroup.Subscribe(key => UpdateKeyPressStats(key, ++numPresses));
});
Run Code Online (Sandbox Code Playgroud)
这可以完美地工作/运行,在KeyPress事件中流,按键推送组,然后跟踪每个键被按下的次数,并UpdateKeyPressStats使用键和新的按键数调用方法.装运它!
但是,FromEventPattern由于对事件的字符串文字引用,我不是签名的粉丝.所以,我想我会尝试一下FromEvent.
// Create an observable from key presses, grouped by the key pressed
var groupedKeyPresses = Observable.FromEvent<KeyPressEventHandler, KeyPressEventArgs>(h => this.KeyPress += h, h => this.KeyPress -= h)
.Select(k => …Run Code Online (Sandbox Code Playgroud) 什么是LINQ to events又名RX Framework又名.NET 4.0中的Reactive Extensions(但也可作为backported版本提供)?
换句话说,System.Reactive.dll中的所有内容是什么?
我想有效地限制事件流,以便在收到第一个事件时调用我的委托,但如果收到后续事件则不会持续1秒.在超时(1秒)到期后,如果收到后续事件,我希望调用我的代理.
使用Reactive Extensions有一种简单的方法吗?
示例代码:
static void Main(string[] args)
{
Console.WriteLine("Running...");
var generator = Observable
.GenerateWithTime(1, x => x <= 100, x => x, x => TimeSpan.FromMilliseconds(1), x => x + 1)
.Timestamp();
var builder = new StringBuilder();
generator
.Sample(TimeSpan.FromSeconds(1))
.Finally(() => Console.WriteLine(builder.ToString()))
.Subscribe(feed =>
builder.AppendLine(string.Format("Observed {0:000}, generated at {1}, observed at {2}",
feed.Value,
feed.Timestamp.ToString("mm:ss.fff"),
DateTime.Now.ToString("mm:ss.fff"))));
Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)
当前输出:
Running...
Observed 064, generated at 41:43.602, observed at 41:43.602
Observed 100, generated at 41:44.165, observed at 41:44.602
Run Code Online (Sandbox Code Playgroud)
但我想观察(时间戳显然会改变)
Running...
Observed 001, generated …Run Code Online (Sandbox Code Playgroud) 用于解释Reactive Extensions(Rx)功能的一个主要示例是将现有鼠标事件组合成一个表示鼠标拖动过程中增量的新"事件":
var mouseMoves = from mm in mainCanvas.GetMouseMove()
let location = mm.EventArgs.GetPosition(mainCanvas)
select new { location.X, location.Y};
var mouseDiffs = mouseMoves
.Skip(1)
.Zip(mouseMoves, (l, r) => new {X1 = l.X, Y1 = l.Y, X2 = r.X, Y2 = r.Y});
var mouseDrag = from _ in mainCanvas.GetMouseLeftButtonDown()
from md in mouseDiffs.Until(
mainCanvas.GetMouseLeftButtonUp())
select md;
Run Code Online (Sandbox Code Playgroud)
资料来源: Matthew Podwysocki的反应框架系列介绍.
在MVVM中,我通常努力使我的.xaml.cs文件尽可能为空,并且使用viewmodel中的命令从视图中连接事件的一种方法纯粹是在标记中使用一种行为:
<Button Content="Click Me">
<Behaviors:Events.Commands>
<Behaviors:EventCommandCollection>
<Behaviors:EventCommand CommandName="MouseEnterCommand" EventName="MouseEnter" />
<Behaviors:EventCommand CommandName="MouseLeaveCommand" EventName="MouseLeave" />
<Behaviors:EventCommand CommandName="ClickCommand" EventName="Click" />
</Behaviors:EventCommandCollection>
</Behaviors:Events.Commands>
</Button>
Run Code Online (Sandbox Code Playgroud)
资料来源: …
我正在努力完成关于PluralSight的Dan Sullivan的Rx Extensions培训课程.这是非常好的东西但不幸的是Rx似乎已经被改变了,尽管该课程仅在一个月前发布.
大多数变化都很容易解决(从三个dll变为单个dll,更改使用的命名空间等)但我很难理解我应该用什么来代替Dan的例子中的Scheduler.Dispatcher.我在调度程序中可用的属性中看不到任何明显的内容.
这是我正在尝试使用(重构的?)Rx库(当前稳定版本v1.0.10605)的代码
var query = from number in Enumerable.Range(1, 25) select StringWait(number.ToString());
var observableQuery = query.ToObservable(Scheduler.ThreadPool);
observableQuery.ObserveOn(Scheduler**.Dispatcher**).Subscribe(n => Results.AppendText(string.Format("{0}\n", n)));
Run Code Online (Sandbox Code Playgroud)
我应该使用什么来调用原始Dispatcher线程上的Observer代码(Results.AppendText)?
我有一个密集的Java背景,所以请原谅我,如果我忽略了C#中明显的东西,但我的研究让我无处可去.我正在尝试使用反应性Rx .NET库.编译器没有抱怨,IObservable但它是对zip方法的调用.它抛出"......你错过了使用指令或汇编参考吗?"
我一直在浏览命名空间,但我找不到想要的东西.System.Reactive如果使用的话,我找不到哪个也会抛出错误,并且此Windows 8.1应用程序已包含所有引用.有人可以告诉我有什么问题吗?
public sealed class EventEngine
{
private static readonly EventEngine singleton = new EventEngine();
public static EventEngine get()
{
return singleton;
}
public IObservable<MusicNote> CurrentKey { get; set; }
public IObservable<Scale> CurrentScale { get; set; }
public IObservable<AppliedScale> CurrentAppliedScale
{
get
{
return CurrentScale.zip(CurrentKey,
(s, k) => AppliedScale.getAppliedScale(k, s));
}
}
private EventEngine() {}
}
Run Code Online (Sandbox Code Playgroud)
*更新*
这是考虑答案输入后的工作版本.
public sealed class EventEngine
{
private static readonly EventEngine singleton = new EventEngine();
public …Run Code Online (Sandbox Code Playgroud) 在我的电子商务应用程序中,我需要在Bing地图中绘制我附近的商店,而我的另一个要求是在缩放和调整地图时我需要根据地图中心更新我的商店.因此,为了实现这一点,我主要选择传统的编码方式.步骤如下.
首次启动我将发送api请求位置,并将在地图上绘制商店.
在Google搜索期间,我发现了许多关于使用Microsoft Rx框架实现类似功能的建议.但没有得到任何正确的代码示例来实现我的目标.任何人都可以帮助我或指导我解决我的问题.请记住,我需要在一次请求中在地图上平均绘制400个商店.
问候,
Stez.
在特定时间内产生Observable值的最惯用方法是什么?例如,假设我有一个从大数组创建的Observable,我想每2秒产生一个值.是的组合interval和selectMany最佳的方式是什么?