public R WithContext <R>(ActorItem self, ActorItem parent, ProcessId sender, ActorRequest request, object msg, Option <SessionId> sessionId, Func <R> f) { var savedContext = ActorContext.Request; var savedSession = ActorContext.SessionId; try { ActorContext.SessionId = sessionId; ActorContext.SetContext(new ActorRequestContext( this, self, sender, parent, msg, request, ProcessFlags.Default, ProcessOpTransaction.Start(self.Actor.Id), (from sid in sessionId from ses in ActorContext.System(self.Actor.Id).Sessions.GetSession(sid) select ses) .IfNoneUnsafe((SessionVector)null) )); return(f()); } finally { ActorContext.SessionId = savedSession; ActorContext.SetContext(savedContext); } }
public static Tuple <Action, FSharpMailboxProcessor <UserControlMessage> > StartUserMailbox <S, T>(IProcess self, ProcessId supervisor, Func <S, T, S> actor, Func <S> setup) { bool active = true; S state = default(S); Action quit = () => active = false; var body = FuncConvert.ToFSharpFunc <FSharpMailboxProcessor <UserControlMessage>, FSharpAsync <Microsoft.FSharp.Core.Unit> >( mbox => CreateAsync <Microsoft.FSharp.Core.Unit>(async() => { ActorContext.SetContext(self, ActorContext.NoSender); state = setup(); while (active) { var msg = await FSharpAsync.StartAsTask(mbox.Receive(FSharpOption <int> .None), FSharpOption <TaskCreationOptions> .None, FSharpOption <CancellationToken> .None); if (msg == null || !active) { active = false; } else { if (msg.MessageType == Message.Type.User) { var umsg = (UserMessage)msg; ActorContext.SetContext(self, umsg.Sender); state = actor(state, (T)((UserMessage)msg).Content); } else if (msg.MessageType == Message.Type.UserControl) { switch (msg.Tag) { case UserControlMessageTag.Shutdown: self.Shutdown(); active = false; break; } } } } (state as IDisposable)?.Dispose(); return(null); }) ); var mailbox = FSharpMailboxProcessor <UserControlMessage> .Start(body, FSharpOption <CancellationToken> .None); mailbox.Error += (object sender, Exception args) => { Process.tell(supervisor, SystemMessage.ChildIsFaulted(self.Id, args)); (state as IDisposable)?.Dispose(); }; return(tuple(quit, mailbox)); }