Пример #1
0
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            /*
             * The dialog/clock is part of the flow.
             * Since it fires events without prior input it is defined as an [ActiveOperation]
             */
            using (var fr = new FlowRuntime())
            {
                var frc = new FlowRuntimeConfiguration();

                // Define flow
                // Feature: close application
                frc.AddStream("Dialog.closed", ".stop");

                // Feature: set alarm
                frc.AddStream("Dialog.setAlarm", "Join.in0");
                frc.AddStream("Dialog.setAlarm", "Alarm switched on");
                frc.AddStream("Clock.now", "Join.in1");
                frc.AddStream("Join", "Calc time diff");
                frc.AddStream("Calc time diff", "Display time diff");

                // Feature: stop alarm
                frc.AddStream("Dialog.stopAlarm", "Join.reset");
                frc.AddStream("Dialog.stopAlarm", "Alarm switched off");
                frc.AddStream("Dialog.stopAlarm", "Stop alarm");

                // Feature: sound alarm
                frc.AddStream("Calc time diff", "Alarm time reached");
                frc.AddStream("Alarm time reached", "Sound alarm");

                fr.Configure(frc);

                // Register operations
                var dlg = new Dialog();
                var clock = new npantarhei.runtime.patterns.operations.Clock();
                var player = new Soundplayer();

                frc.AddOperation(dlg)
                   .AddOperation(clock)
                   .AddAction("Alarm switched off", dlg.Alarm_switched_off).MakeSync()
                   .AddAction("Alarm switched on", dlg.Alarm_switched_on).MakeSync()
                   .AddAction<TimeSpan>("Alarm time reached", Alarm_time_reached)
                   .AddFunc<Tuple<DateTime,DateTime>,TimeSpan>("Calc time diff", Calc_time_diff)
                   .AddAction<TimeSpan>("Display time diff", dlg.Display_time_diff).MakeSync()
                   .AddManualResetJoin<DateTime, DateTime>("Join")
                   .AddAction("Sound alarm", player.Start_playing)
                   .AddAction("Stop alarm", player.Stop_playing);
                fr.Configure(frc);

                fr.Message += Console.WriteLine;
                fr.UnhandledException += Console.WriteLine;

                // Execute flow
                // Feature: start application
                Application.Run(dlg); // needs to run on this thread; cannot be done on flow runtime thread.
            }
        }
Пример #2
0
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            /*
             * The dialog/clock is part of the flow.
             * Since it fires events without prior input it is defined as an [ActiveOperation]
             */
            using (var fr = new FlowRuntime())
            {
                var frc = new FlowRuntimeConfiguration();

                // Define flow
                // Feature: close application
                frc.AddStream("Dialog.closed", ".stop");

                // Feature: set alarm
                frc.AddStream("Dialog.setAlarm", "Join.in0");
                frc.AddStream("Dialog.setAlarm", "Alarm switched on");
                frc.AddStream("Clock.now", "Join.in1");
                frc.AddStream("Join", "Calc time diff");
                frc.AddStream("Calc time diff", "Display time diff");

                // Feature: stop alarm
                frc.AddStream("Dialog.stopAlarm", "Join.reset");
                frc.AddStream("Dialog.stopAlarm", "Alarm switched off");
                frc.AddStream("Dialog.stopAlarm", "Stop alarm");

                // Feature: sound alarm
                frc.AddStream("Calc time diff", "Alarm time reached");
                frc.AddStream("Alarm time reached", "Sound alarm");

                fr.Configure(frc);

                // Register operations
                var dlg    = new Dialog();
                var clock  = new npantarhei.runtime.patterns.operations.Clock();
                var player = new Soundplayer();

                frc.AddOperation(dlg)
                .AddOperation(clock)
                .AddAction("Alarm switched off", dlg.Alarm_switched_off).MakeSync()
                .AddAction("Alarm switched on", dlg.Alarm_switched_on).MakeSync()
                .AddAction <TimeSpan>("Alarm time reached", Alarm_time_reached)
                .AddFunc <Tuple <DateTime, DateTime>, TimeSpan>("Calc time diff", Calc_time_diff)
                .AddAction <TimeSpan>("Display time diff", dlg.Display_time_diff).MakeSync()
                .AddManualResetJoin <DateTime, DateTime>("Join")
                .AddAction("Sound alarm", player.Start_playing)
                .AddAction("Stop alarm", player.Stop_playing);
                fr.Configure(frc);

                fr.Message            += Console.WriteLine;
                fr.UnhandledException += Console.WriteLine;

                // Execute flow
                // Feature: start application
                Application.Run(dlg); // needs to run on this thread; cannot be done on flow runtime thread.
            }
        }
Пример #3
0
        public void No_processing_Just_redirect_input_to_output()
        {
            var frc = new FlowRuntimeConfiguration().AddStream(new Stream(".in", ".out"));

            _sut.Configure(frc);

            _sut.Process(new Message(".in", "hello"));

            Assert.IsTrue(_are.WaitOne(1000));
            Assert.AreEqual(".out", _result.Port.Fullname);
            Assert.AreEqual("hello", _result.Data.ToString());
        }
        public void Run_flat()
        {
            using (var fr = new FlowRuntime())
            {
                /*
                 * (.in) -> (Split) -> (Map) -> (Build) -> (.out)
                 */
                var frc = new FlowRuntimeConfiguration();
                frc.AddStream(new Stream(".in", "Split"));
                frc.AddStream(new Stream("Split", "Map"));
                frc.AddStream(new Stream("Map", "Build"));
                frc.AddStream(new Stream("Build", ".out"));

                frc.AddFunc<string, IEnumerable<string>>("Split", configuration => configuration.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries));
                frc.AddAction<IEnumerable<string>, IEnumerable<KeyValuePair<string, string>>>("Map", Map);
                frc.AddFunc<IEnumerable<KeyValuePair<string, string>>, Dictionary<string, string>>("Build", Build);
                fr.Configure(frc);

                Dictionary<string, string> dict = null;
                var are = new AutoResetEvent(false);
                fr.Result += _ =>
                                {
                                    dict = (Dictionary<string, string>) _.Data;
                                    are.Set();
                                };

                fr.Process(new Message(".in", "a=1;b=2"));

                Assert.IsTrue(are.WaitOne(500));
                Assert.AreEqual(2, dict.Count);
                Assert.AreEqual("1", dict["a"]);
                Assert.AreEqual("2", dict["b"]);
            }
        }
Пример #5
0
        static void Main2(string[] args)
        {
            using (var fr = new FlowRuntime())
            {
                var frc = new FlowRuntimeConfiguration();
                frc.AddStream(".in", "Find_files");
                frc.AddStream("Find_files", "scatter");
                frc.AddStream("scatter.stream", "Count_words");
                frc.AddStream("scatter.count", "gather.count");
                frc.AddStream("Count_words", "gather.stream");
                frc.AddStream("gather", "Total");
                frc.AddStream("Total", ".out");

                frc.AddFunc <string, IEnumerable <String> >("Find_files", Find_files).MakeAsync()
                .AddFunc <string, int>("Count_words", Count_words).MakeParallel()
                .AddFunc <IEnumerable <int>, Tuple <int, int> >("Total", Total)
                .AddOperation(new Scatter <string>("scatter"))
                .AddOperation(new Gather <int>("gather"));

                fr.Configure(frc);

                var start = DateTime.Now;
                fr.Process(new Message(".in", "x"));

                Tuple <int, int> result = null;
                fr.WaitForResult(5000, _ => result = (Tuple <int, int>)_.Data);
                var delta = DateTime.Now.Subtract(start);

                Console.WriteLine("{0} words in {1} files, {2}msec", result.Item2, result.Item1, delta);
            }
        }
Пример #6
0
        static void Main(string[] args)
        {
            using (var fr = new FlowRuntime())
            {
                var frc = new FlowRuntimeConfiguration();
                frc.AddStream(".in", "Pushc");
                frc.AddStream("Pushc", "Find Files");
                frc.AddStream("Pushc.exception", "Handle Exception");
                frc.AddStream("Find Files", "Count Words");
                frc.AddStream("Count Words", "popc");
                frc.AddStream("Popc", "Total");
                frc.AddStream("Total", ".out");

                frc.AddFunc <IEnumerable <string>, IEnumerable <int> >("Count Words", Count_words3)
                .AddFunc <string, IEnumerable <String> >("Find Files", Find_files)
                .AddAction <FlowRuntimeException>("Handle Exception", Handle_exception)
                .AddPopCausality("Popc")
                .AddPushCausality("Pushc")
                .AddFunc <IEnumerable <int>, Tuple <int, int> >("Total", Total);
                fr.Configure(frc);

                fr.Process(new Message(".in", "x"));

                Tuple <int, int> result = null;
                fr.WaitForResult(5000, _ => result = (Tuple <int, int>)_.Data);

                if (result != null)
                {
                    Console.WriteLine("{0} words in {1} files", result.Item2, result.Item1);
                }
            }
        }
Пример #7
0
        static void Main(string[] args)
        {
            using (var fr = new FlowRuntime())
            {
                var frc = new FlowRuntimeConfiguration();
                frc.AddStream(".in", "Pushc");
                frc.AddStream("Pushc", "Find Files");
                frc.AddStream("Pushc.exception", "Handle Exception");
                frc.AddStream("Find Files", "Count Words");
                frc.AddStream("Count Words", "popc");
                frc.AddStream("Popc", "Total");
                frc.AddStream("Total", ".out");

                frc.AddFunc<IEnumerable<string>, IEnumerable<int>>("Count Words", Count_words3)
                   .AddFunc<string, IEnumerable<String>>("Find Files", Find_files)
                   .AddAction<FlowRuntimeException>("Handle Exception", Handle_exception)
                   .AddPopCausality("Popc")
                   .AddPushCausality("Pushc")
                   .AddFunc<IEnumerable<int>, Tuple<int, int>>("Total", Total);
                fr.Configure(frc);

                fr.Process(new Message(".in", "x"));

                Tuple<int, int> result = null;
                fr.WaitForResult(5000, _ => result = (Tuple<int, int>)_.Data);

                if (result != null)
                    Console.WriteLine("{0} words in {1} files", result.Item2, result.Item1);
            }
        }
Пример #8
0
        static void Main(string[] args)
        {
            using (var fr = new FlowRuntime())
            {
                var frc = new FlowRuntimeConfiguration();
                frc.AddStream(".in", "A");
                frc.AddStream("A", "B");
                frc.AddStream("B", "C");

                frc.AddFunc <int, int>("A", i => i + 1)
                .AddFunc <int, int>("B", i => i * 2)
                .AddAction <int>("C", (int i) => Console.WriteLine("={0}", i));
                fr.Configure(frc);

                // Trace messages selectively using Rx
                var tracer = new Subject <IMessage>();
                tracer.Where(msg => msg.Port.OperationName == "B") // message filter
                .Select(msg => (int)msg.Data)
                .Subscribe(i => Console.WriteLine("{0} -> B", i),  // message handler
                           _ => { });
                fr.Message += tracer.OnNext;


                fr.Process(new Message(".in", 1));
                fr.Process(new Message(".in", 2));
                fr.Process(new Message(".in", 3));

                fr.WaitForResult(500);
            }
        }
        private static void Main(string[] args)
        {
            _email = ConfigurationManager.AppSettings["GoogleAccount"];
            _baseDirPath = String.IsNullOrEmpty(ConfigurationManager.AppSettings["BasePath"]) ? @"c:\temp\" : ConfigurationManager.AppSettings["BasePath"];
            _deleteOlderFiles = bool.Parse(String.IsNullOrEmpty(ConfigurationManager.AppSettings["DeleteOlderFiles"]) ? "false" : ConfigurationManager.AppSettings["DeleteOlderFiles"]);
            _label = "Listen Subscriptions";
            _dateFormat = "yyyyMMddTHHmmss";
            _getFilesFromTheLastXDays =
                int.Parse(String.IsNullOrEmpty(ConfigurationManager.AppSettings["GetFilesFromTheLastXDays"]) ? "3" : ConfigurationManager.AppSettings["GetFilesFromTheLastXDays"]);
            _reader = null;

            //Console.WriteLine("Enter password");
            var password = "******";//  Console.ReadLine();

            _reader = Reader.CreateReader(_email, password, "scroll") as Reader;

            using (var fr = new FlowRuntime())
            {
                var frc = new FlowRuntimeConfiguration();
                frc.AddStream(".in", "Get_Feeds");
                frc.AddStream("Get_Feeds", ".out");

                frc.AddFunc<Reader, IEnumerable<UrlAndFeed>>("Get_Feeds", getFeedsWithGivenLabel);

                fr.Configure(frc);

                fr.Process(new Message(".in", _reader));

                fr.WaitForResult(5000, _ => Console.WriteLine(_.Data));

                Console.ReadLine();
            }
        }
Пример #10
0
        public void Run_flat()
        {
            using (var fr = new FlowRuntime())
            {
                /*
                 * (.in) -> (Split) -> (Map) -> (Build) -> (.out)
                 */
                var frc = new FlowRuntimeConfiguration();
                frc.AddStream(new Stream(".in", "Split"));
                frc.AddStream(new Stream("Split", "Map"));
                frc.AddStream(new Stream("Map", "Build"));
                frc.AddStream(new Stream("Build", ".out"));

                frc.AddFunc <string, IEnumerable <string> >("Split", configuration => configuration.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
                frc.AddAction <IEnumerable <string>, IEnumerable <KeyValuePair <string, string> > >("Map", Map);
                frc.AddFunc <IEnumerable <KeyValuePair <string, string> >, Dictionary <string, string> >("Build", Build);
                fr.Configure(frc);

                Dictionary <string, string> dict = null;
                var are = new AutoResetEvent(false);
                fr.Result += _ =>
                {
                    dict = (Dictionary <string, string>)_.Data;
                    are.Set();
                };

                fr.Process(new Message(".in", "a=1;b=2"));

                Assert.IsTrue(are.WaitOne(500));
                Assert.AreEqual(2, dict.Count);
                Assert.AreEqual("1", dict["a"]);
                Assert.AreEqual("2", dict["b"]);
            }
        }
Пример #11
0
        static void Main(string[] args)
        {
            using(var fr = new FlowRuntime())
            {
                var frc = new FlowRuntimeConfiguration();
                frc.AddStream(".in", "A");
                frc.AddStream("A", "B");
                frc.AddStream("B", "C");

                frc.AddFunc<int, int>("A", i => i + 1)
                   .AddFunc<int, int>("B", i => i * 2)
                   .AddAction<int>("C", (int i) => Console.WriteLine("={0}", i));
                fr.Configure(frc);

                // Trace messages selectively using Rx
                var tracer = new Subject<IMessage>();
                tracer.Where(msg => msg.Port.OperationName == "B") // message filter
                      .Select(msg => (int)msg.Data)
                      .Subscribe(i => Console.WriteLine("{0} -> B", i), // message handler
                                 _ => { });
                fr.Message += tracer.OnNext;

                fr.Process(new Message(".in", 1));
                fr.Process(new Message(".in", 2));
                fr.Process(new Message(".in", 3));

                fr.WaitForResult(500);
            }
        }
Пример #12
0
        static void Main(string[] args)
        {
            using (var fr = new FlowRuntime())
            {
                var frc = new FlowRuntimeConfiguration();

                var pageBufferContainer = new DataContainer <PageBuffer>();

                var frontend = new Frontend();

                frc.AddFlow(new Main(new Formatter(),
                                     frontend));
                frc.AddFlow(new Features(new CommandlineParser(pageBufferContainer),
                                         new TextFileAdapter(),
                                         new LineBuffer(pageBufferContainer),
                                         new Pager(pageBufferContainer)));
                fr.Configure(frc);

                frontend.displayFirstPage += fr.CreateEventProcessor(".displayFirstPage");
                frontend.displayLastPage  += fr.CreateEventProcessor(".displayLastPage");
                frontend.displayNextPage  += fr.CreateEventProcessor(".displayNextPage");
                frontend.displayPrevPage  += fr.CreateEventProcessor(".displayPrevPage");

                //fr.Message += Console.WriteLine;

                fr.Process(new Message(".run", new[] { "test1.txt" }));

                fr.WaitForResult();
            }
        }
Пример #13
0
        static void Main(string[] args)
        {
            using(var fr = new FlowRuntime())
            {
                var frc = new FlowRuntimeConfiguration();

                var pageBufferContainer = new DataContainer<PageBuffer>();

                var frontend = new Frontend();

                frc.AddFlow(new Main(new Formatter(),
                                    frontend));
                frc.AddFlow(new Features(new CommandlineParser(pageBufferContainer),
                                        new TextFileAdapter(),
                                        new LineBuffer(pageBufferContainer),
                                        new Pager(pageBufferContainer)));
                fr.Configure(frc);

                frontend.displayFirstPage += fr.CreateEventProcessor(".displayFirstPage");
                frontend.displayLastPage += fr.CreateEventProcessor(".displayLastPage");
                frontend.displayNextPage += fr.CreateEventProcessor(".displayNextPage");
                frontend.displayPrevPage += fr.CreateEventProcessor(".displayPrevPage");

                //fr.Message += Console.WriteLine;

                fr.Process(new Message(".run", new[]{"test1.txt"}));

                fr.WaitForResult();
            }
        }
Пример #14
0
        public static void Main() {
            using (var fr = new FlowRuntime()) {
                fr.Message += Console.WriteLine;
                fr.UnhandledException += ex => MessageBox.Show(ex.ToString());

                var mainWindow = new MainWindow();
                var viewModel = new MainWindowVM();
                mainWindow.DataContext = viewModel;
                var mapper = new Mapper(viewModel);
                var metronom = new Metronom(new Play());
                var stopuhr = new Stopuhr();
                var pausenuhr = new Pausenuhr();
                var aufgabentimer = new Timer("aufgaben_timer");
                var pausentimer = new Timer("pausen_timer");
                var uebungsdauertimer = new Timer("uebungsdauer_timer");
                var repository = new Repository();

                var frc = new FlowRuntimeConfiguration();

                frc.AddStreamsFrom("metronom.logik.flows.root.flow", typeof(Metronom).Assembly);

                frc.AddAction<string>("aufgabe_laden", repository.Naechste_Aufgabe)
                    .AddAction<Metrum>("metrum_laden", repository.Naechstes_Metrum)
                    .AddAction("ende_der_aufgaben", repository.Ende_der_Aufgaben)
                    .AddAction<string>("aufgabe_anzeigen", mapper.Aufgabe_anzeigen)
                    .AddOperation(aufgabentimer)
                    .AddFunc<Metrum, int>("timer_konfigurieren", metronom.Timer_konfigurieren)
                    .AddAction("metronom_click", metronom.Click)
                    .AddFunc("uebungsdauer_timer_konfigurieren", stopuhr.Timer_konfigurieren)
                    .AddFunc("uebungsdauer_ermitteln", stopuhr.Uebungsdauer_ermitteln)
                    .AddOperation(uebungsdauertimer)
                    .AddAction<string>("uebungsdauer_anzeigen", mapper.Uebungsdauer_anzeigen)
                    .AddAction<string>("restdauer_anzeigen", mapper.Restdauer_anzeigen)
                    .AddAction("aufgabentimer_ausschalten", aufgabentimer.Stop)
                    .AddFunc("pausentimer_konfigurieren", pausenuhr.Pausentimer_konfigurieren)
                    .AddAction("pausentimer_ausschalten", pausentimer.Stop)
                    .AddFunc("restdauer_ermitteln", pausenuhr.Restdauer_ermitteln)
                    .AddOperation(pausentimer)
                    .AddAction<int>("restdauer_pruefen", pausenuhr.Restdauer_pruefen)
                    .AddAction("uebungsdauer_timer_ausschalten", uebungsdauertimer.Stop)
                    ;
                fr.Configure(frc);

                mainWindow.Start += fr.CreateEventProcessor(".start");
                mainWindow.Pause += fr.CreateEventProcessor(".pause");

                var app = new Application { MainWindow = mainWindow };
                app.Run(mainWindow);
            }
        }
Пример #15
0
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            /*
             * The dialog/clock are outside the flow; they are viewed as part of the environment.
             * They are bound to the flow as event source using CreateEventProcessor().
             */
            using (var fr = new FlowRuntime())
            {
                var frc = new FlowRuntimeConfiguration();

                // Register streams
                frc.AddStreamsFrom("Alarm_clock.Flow2.flow", typeof(Program2).Assembly);

                // Register operations
                var dlg    = new Dialog2();
                var clock  = new Clock2();
                var player = new Soundplayer();

                frc.AddAction("Alarm switched off", dlg.Alarm_switched_off).MakeSync()
                .AddAction("Alarm switched on", dlg.Alarm_switched_on).MakeSync()
                .AddAction <TimeSpan>("Alarm time reached", Alarm_time_reached)
                .AddFunc <Tuple <DateTime, DateTime>, TimeSpan>("Calc time diff", Calc_time_diff)
                .AddAction <TimeSpan>("Display time diff", dlg.Display_time_diff).MakeSync()
                .AddManualResetJoin <DateTime, DateTime>("Join")
                .AddAction("Sound alarm", player.Start_playing)
                .AddAction("Stop alarm", player.Stop_playing);
                fr.Configure(frc);

                // Wire-up event sources
                dlg.SetAlarm      += fr.CreateEventProcessor <DateTime>(".setAlarm");
                dlg.ResetAlarm    += fr.CreateEventProcessor(".resetAlarm");
                clock.CurrentTime += fr.CreateEventProcessor <DateTime>(".now");

                fr.Message            += Console.WriteLine;
                fr.UnhandledException += Console.WriteLine;

                // Execute flow
                // Feature: start application
                Application.Run(dlg); // needs to run on this thread; cannot be done on flow runtime thread.
            }
        }
Пример #16
0
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            /*
             * The dialog/clock are outside the flow; they are viewed as part of the environment.
             * They are bound to the flow as event source using CreateEventProcessor().
             */
            using(var fr = new FlowRuntime())
            {
                var frc = new FlowRuntimeConfiguration();

                // Register streams
                frc.AddStreamsFrom("Alarm_clock.Flow2.flow", typeof(Program2).Assembly);

                // Register operations
                var dlg = new Dialog2();
                var clock = new Clock2();
                var player = new Soundplayer();

                frc.AddAction("Alarm switched off", dlg.Alarm_switched_off).MakeSync()
                   .AddAction("Alarm switched on", dlg.Alarm_switched_on).MakeSync()
                   .AddAction<TimeSpan>("Alarm time reached", Alarm_time_reached)
                   .AddFunc<Tuple<DateTime, DateTime>, TimeSpan>("Calc time diff", Calc_time_diff)
                   .AddAction<TimeSpan>("Display time diff", dlg.Display_time_diff).MakeSync()
                   .AddManualResetJoin<DateTime, DateTime>("Join")
                   .AddAction("Sound alarm", player.Start_playing)
                   .AddAction("Stop alarm", player.Stop_playing);
                fr.Configure(frc);

                // Wire-up event sources
                dlg.SetAlarm += fr.CreateEventProcessor<DateTime>(".setAlarm");
                dlg.ResetAlarm += fr.CreateEventProcessor(".resetAlarm");
                clock.CurrentTime += fr.CreateEventProcessor<DateTime>(".now");

                fr.Message += Console.WriteLine;
                fr.UnhandledException += Console.WriteLine;

                // Execute flow
                // Feature: start application
                Application.Run(dlg); // needs to run on this thread; cannot be done on flow runtime thread.
            }
        }
Пример #17
0
        static void Main2(string[] args)
        {
            using(var fr = new FlowRuntime())
            {
                var frc = new FlowRuntimeConfiguration();
                frc.AddStream(".in", "Find_files");
                frc.AddStream("Find_files", "scatter");
                frc.AddStream("scatter.stream", "Count_words");
                frc.AddStream("scatter.count", "gather.count");
                frc.AddStream("Count_words", "gather.stream");
                frc.AddStream("gather", "Total");
                frc.AddStream("Total", ".out");

                frc.AddFunc<string, IEnumerable<String>>("Find_files", Find_files).MakeAsync()
                   .AddFunc<string,int>("Count_words", Count_words).MakeParallel()
                   .AddFunc<IEnumerable<int>, Tuple<int,int>>("Total", Total)
                   .AddOperation(new Scatter<string>("scatter"))
                   .AddOperation(new Gather<int>("gather"));

                fr.Configure(frc);

                var start = DateTime.Now;
                fr.Process(new Message(".in", "x"));

                Tuple<int,int> result = null;
                fr.WaitForResult(5000, _ => result = (Tuple<int,int>)_.Data);
                var delta = DateTime.Now.Subtract(start);

                Console.WriteLine("{0} words in {1} files, {2}msec", result.Item2, result.Item1, delta);
            }
        }