0

I would like to convert a blocking IEnumerable (possibly infinite) into messages sent to an Actor. What is the best way to do this? I am currently attempting to create a Task within an actor on PreStart and inside the task have it send messages to but it doesn't seem to be working.

I've read some pages about preferring to use PipeTo to wrap a Task but that seems to only be used to retrieve a single result rather than have a separate process continually sending values.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Akka.Actor;

namespace Junk
{
    public class Program
    {
        public static void Main()
        {
            var system = ActorSystem.Create("my-system");
            var actor = system.ActorOf(Props.Create(() => new Manager()));

            Console.ReadLine();
        }
    }

    public class Manager : ReceiveActor
    {
        private Task _task;

        public Manager() {
          Receive<uint>(msg => { Console.WriteLine($"received {msg}"); });
        }

        protected override void PreStart() {
          Console.WriteLine($"{Self} - PreStart --------------");
          startTask();
        }

        private void startTask() {
          _task = Task.Factory.StartNew(() => {
            BlockingEnumerable source = new BlockingEnumerable();
            Console.WriteLine($"task starting loop -------------");
            foreach (uint v in source) {
              Self.Tell(v);
            }
          });
        }
    }

    public class BlockingEnumerable : IEnumerable<uint>
    {
        public IEnumerator<uint> GetEnumerator() { return new BlockingEnumerator(); }
        IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
    }

    public class BlockingEnumerator : IEnumerator<uint>
    {
        private uint value = 0;
        public uint Current => value;
        object IEnumerator.Current => Current;
        public void Dispose() { }
        public bool MoveNext() { Thread.Sleep(2000); value += 1; return true; }
        public void Reset() { value = 0; }
    }
}
Danny G
  • 581
  • 4
  • 16
  • 1
    [BlockingCollection Class](https://msdn.microsoft.com/en-us/library/dd267312(v=vs.110).aspx) – Fabio Apr 25 '17 at 03:33
  • What do you need it for? Maybe Akka.Streams is what you actually want? – Bartosz Sypytkowski Apr 25 '17 at 13:13
  • I am streaming extended events from SQL Server and the interface provided (that I can find) is an IEnumerable. I would like to have these stream sessions managed by an actor and subscribe-able by other actors or other outputs. I'll take a look to see if Akka.Streams provides something. – Danny G Apr 25 '17 at 14:20
  • If you're using Akka.Persistence eventsourcing, then SQL journals do have support for something called Peristence Queries, which expose event streams into format readable from Akka.Streams API. – Bartosz Sypytkowski Apr 25 '17 at 16:53

0 Answers0