.
Anmeldung | Registrieren | Hilfe
in Suchen

Anfängerproblem Mit Rx

Letzter Beitrag 04. Sep 2010 18:14 von Rainer Hilmer. 1 Antworten.
Seite 1 von 1 (2 Treffer)
Beiträge sortieren: Zurück Weiter
  • 04. Sep 2010 14:19

    • Rainer Hilmer
    • Top 10 Mitwirkender
      Männlich
    • Registriert am 22. Jan 2008
    • Braunschweig
    • Beiträge 927
    • Punkte 14.105

    Anfängerproblem Mit Rx

    Hallo,
    diese ganzen Blogartikel über Rx sind ja schön und gut, sie haben nur alle die gleiche Krankheit.
    1. Sie arbeiten mit Zahlen - da funzt Observable.Interval ganz hervorragend!
    2. Observable und Observer liegen in der gleichen Demomethode -easy.

    Nachdem ich den 7teiligen Artikel von Lee Campbell gelesen hatte, wollte ich ein erstes Experiment starten und bin prompt auf die Nase geflogen. Ich stochere jetzt schon den halben Tag im Dunkeln, dabei will ich doch nur folgendes:

    Windows Form mit einem Start/Stop-Button und einer Pircturebox. Diese Picturebox soll im 500ms-Takt blinken (siehe http://dotnet-forum.de/KnowledgeBase/articles/2010/08/29/350-controls-aus-einem-anderen-thread-setzen-synchronizationcontext-cancellationtoken-bonus-tooltips-.aspx )

    Das ganze jetzt nur bitte über Rx. Kann mir jemand unter die Arme greifen?

    Gruß,
    Rainer
    Abgelegt unter: ,
    • IP-Adresse ist Registriert
  • 04. Sep 2010 18:14 Antwort zu

    • Rainer Hilmer
    • Top 10 Mitwirkender
      Männlich
    • Registriert am 22. Jan 2008
    • Braunschweig
    • Beiträge 927
    • Punkte 14.105

    Anfängerproblem Mit Rx

    Ach wie schön und einfach kann das Leben doch sein, wenn ich einmal Ruhe zum Nachdenken habe! Vielleicht ist meine Lösung für andere Rx-Einsteiger ja auch interessant.
    Nur mit diesem subscriptions-Array bin ich unzufrieden. Das ist eine Krücke. Hat jemand eine bessere Idee wie ich "access to modified closure" verhindern kann (zweiter Code-Block, im Button2Click-Eventhandler)?

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Drawing;
    using System.Linq;
    using System.Threading;
    
    
    namespace ControlInvokationRxStyle
    {
       internal static class ColorWorker
       {
          internal static bool Trigger;
    
    
          internal static IObservable<Color> GetColdColorStream()
          {
             return Observable.Create<Color>(
                color =>
                {
                   while(Trigger)
                   {
                      color.OnNext(Color.LimeGreen);
                      Thread.Sleep(500);
                      color.OnNext(Color.BlueViolet);
                      Thread.Sleep(500);
                   }
                   return () => { };
                });
          }
    
    
          // Ohne RefCount IConnectableObservable.
          internal static IObservable<Color> HotColorStream()
          {
             var timerHook = Observable.Interval(TimeSpan.FromMilliseconds(500));
             return Observable.Create<Color>(
                color =>
                {
                   timerHook.Subscribe(x => color.OnNext(x % 2 != 0
                      ? Color.LimeGreen
                      : Color.BlueViolet));
                   return () => { };
                })
                // Note: Just for demonstration --->|
               .Do(color => Debug.WriteLine("Publishing {0}", color.ToString()))
               //|<---
               .Publish()
               .RefCount();
          }
       }
    }

    using System;
    using System.Concurrency;
    using System.Disposables;
    using System.Linq;
    using System.Windows.Forms;
    
    
    namespace ControlInvokationRxStyle
    {
       public partial class Form1 : Form
       {
          private readonly ControlScheduler led1Scheduler;
          private readonly ControlScheduler led2Scheduler;
          private bool connect;
    
    
          public Form1()
          {
             InitializeComponent();
             FormBorderStyle = FormBorderStyle.Fixed3D;
             MaximizeBox = false;
             SizeGripStyle = SizeGripStyle.Hide;
             led1Scheduler = new ControlScheduler(LED1);
             led2Scheduler = new ControlScheduler(LED2);
             connect = false;
          }
    
    
          private void Button1Click(object sender, EventArgs e)
          {
             ColorWorker.Trigger = !ColorWorker.Trigger;
             var stream = ColorWorker.GetColdColorStream();
             stream.SubscribeOn(Scheduler.NewThread)
                   .ObserveOn(led1Scheduler)
                   .Subscribe(color => LED1.BackColor = color);
          }
    
    
          private void Button2Click(object sender, EventArgs e)
          {
             connect = !connect;
             if(!connect)
                return;
             var stream = ColorWorker.HotColorStream();
             IDisposable[] subscriptions = { Disposable.Empty };
             /* Note: Zugriff über Array-Element um "access to modified
              * closure" zu verhindern. */
             subscriptions[0] = stream.SubscribeOn(Scheduler.NewThread)
                .ObserveOn(led2Scheduler)
                .Subscribe(color =>
                              {
                                 LED2.BackColor = color;
                                 if(!connect)
                                    subscriptions[0].Dispose();
                              });
             // Wird durch den Einsatz von RefCount nicht benötigt:
             //stream.Connect();
          }
       }
    }

    Gruß,
    Rainer
    • IP-Adresse ist Registriert
Seite 1 von 1 (2 Treffer)

WPF Forum | ASP.NET Forum | ASP.NET MVC Forum | Silverlight Forum | Windows Phone 7 Forum | SharePoint Forum | Dotnet Jobs | Dotnet Termine | Developer Blogs | Dotnet News

Das Team | Regeln | Impressum