読者です 読者をやめる 読者になる 読者になる

謎言語使いの徒然

適当に気になった技術や言語を流すブログ。

VOICEROID+でSkypeメッセージ喋らせる(5)

日記 Tips

それぞれのVOICEROIDをスレッド化して、相互に干渉なしで喋れるようActor作った。

namespace net.azworks.actor
{
    abstract class ActorBase<T>
    {
        public T State { get; set; }

        public void SendMessage(T message)
        {
            this.allMessages.Enqueue(message);

            lock (this)
            {
                if (this.activeTask != null)
                    return;

                activeTask = new Thread(new ThreadStart(ExecuteActions));
                activeTask.SetApartmentState(ApartmentState.STA);
                activeTask.Start();
            }
        }

        private readonly ConcurrentQueue<T> allMessages = new ConcurrentQueue<T>();

        private Thread activeTask;

        public event EventHandler<UnhandledExceptionEventArgs> OnError;

        abstract protected void Act(T message);

        private void ExecuteActions()
        {
            T sample;
            while (allMessages.TryDequeue(out sample))
            {
                this.State = sample;
                try
                {
                    this.Act(sample);
                }
                catch (Exception e)
                {
                    UnhandledExceptionEventArgs except = new UnhandledExceptionEventArgs(e, false);
                    if (this.OnError != null)
                        this.OnError.Invoke(this, except);
                }
            }

            lock (this)
            {
                this.activeTask = null;
            }
        }
    }
}

例外処理なんぞ最初からやる気なし。
オーバーライドして Act を実装して SendMessage するだけ。
STA 属性ついてるのは、、、知らん。