如何将阻止IEnumerable转换为Akka actor

时间:2017-04-25 03:22:46

标签: c# akka.net

我想将阻塞的IEnumerable(可能是无限的)转换为发送给Actor的消息。做这个的最好方式是什么?我目前正在尝试在Task上的actor中创建PreStart,并且在任务内部让它发送消息但它似乎没有工作。

我已经阅读了一些关于更喜欢使用PipeTo来包装Task的页面,但这似乎只用于检索单个结果,而不是让一个单独的进程不断发送值。

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; }
    }
}

0 个答案:

没有答案