我想将阻塞的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; }
}
}