根据您的需要,有不同的方法可以做到这一点,而不是只有一个“正确”的答案。
您可以使用Persistent Actor在启动时自动从持久存储中恢复状态(或在崩溃的情况下进行恢复)。或者,如果您不想使用该模块(截至 2015 年 7 月仍处于测试阶段),您可以自己使用以下两种方法之一:
1) 您可以在 中加载您的状态PreStart
,但如果您可以通过数据库客户端使操作异步并使用该PipeTo
模式将结果逐步发送回您自己,我只会这样做。但是,如果您需要在开始工作之前将所有状态都保存在内存中,那么您需要...
2)使用行为切换制作一个有限状态机。从门控状态开始,向自己发送一条消息以加载数据,并存储所有进入的内容。然后切换到接收状态并在状态加载完成后取消存储所有消息。这是我更喜欢的方法。
示例(只是用 a 模拟数据库负载Task
):
public class ProductActor : ReceiveActor, IWithUnboundedStash
{
public IStash Stash { get; set; }
public ProductActor()
{
// begin in gated state
BecomeLoading();
}
private void BecomeLoading()
{
Become(Loading);
LoadInitialState();
}
private void Loading()
{
Receive<DoneLoading>(done =>
{
BecomeReady();
});
// stash any messages that come in until we're done loading
ReceiveAny(o =>
{
Stash.Stash();
});
}
private void LoadInitialState()
{
// load your state here async & send back to self via PipeTo
Task.Run(() =>
{
// database loading task here
return new Object();
}).ContinueWith(tr =>
{
// do whatever (e.g. error handling)
return new DoneLoading();
}).PipeTo(Self);
}
private void BecomeReady()
{
Become(Ready);
// our state is ready! put all those stashed messages back in the mailbox
Stash.UnstashAll();
}
private void Ready()
{
// handle those unstashed + new messages...
ReceiveAny(o =>
{
// do whatever you need to do...
});
}
}
/// <summary>
/// Marker interface.
/// </summary>
public class DoneLoading {}