Ответ кросс-пост от Rx Forum (если автор здесь и хочет это сделать, это нормально для меня):
Проблема № 1: Вы используете старые биты. Observable.Context пропал около 4-х версий назад.
Проблема № 2: Javascript не имеет понятия о потоках, а Rx любит помещать вещи в другие потоки для вас.
Итак, используя последние биты, решение выглядит примерно так:
void Form1_Load(object sender, EventArgs e)
{
Reactive("Time flies like an arrow");
}
private void Reactive(string msg)
{
var mousemove = Observable.FromEvent<MouseEventArgs>(this, "MouseMove");
var message = msg.ToCharArray();
for(int i = 0; i < message.Length; i++)
{
var l = new Label()
{
Text = message[i].ToString(),
AutoSize = true,
TextAlign = ContentAlignment.MiddleCenter
};
int closure = i;
mousemove
.Delay(TimeSpan.FromSeconds(0.07 * i), Scheduler.Dispatcher)
.Subscribe(e =>
{
l.Left = e.EventArgs.X + closure * 12 - 5;
l.Top = e.EventArgs.Y + 15;
});
Controls.Add(l);
}
}
Обратите внимание на ObserveOnDispatcher и SubscribeOnDispatcher. Это приближает нас к версии Javascript, но, опять же, реальная проблема - это реальная проблема.
ОБНОВЛЕНИЕ , добавлено исправление от Джеффа Ван Гога в приведенном выше коде
Просто для забавы, вот расплывчатый рендеринг того же самого без Rx:
private void Unreactive(string msg)
{
var message = msg.ToCharArray();
for(int i = 0; i < message.Length; i++)
{
var l = new Label()
{
Text = message[i].ToString(),
AutoSize = true,
TextAlign = ContentAlignment.MiddleCenter
};
Controls.Add(l);
int closure = i;
this.MouseMove += (s, e) => LabelDelayMove(closure, e, l);
}
}
private void LabelDelayMove(int i, MouseEventArgs e, Label l)
{
Point p = new Point(e.X + i * 12 - 5, e.Y - 15);
var timer = new System.Threading.Timer((_) => LabelMove(l, p), null, i * 70, System.Threading.Timeout.Infinite);
}
private void LabelMove(Label l, Point location)
{
this.BeginInvoke(new Action(() => l.Location = location));
}