ui/wpf/UIcore/Application.cs

Sat, 24 Jan 2015 19:16:38 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 24 Jan 2015 19:16:38 +0100
changeset 79
052224670baf
parent 78
135920fe441b
child 81
5eb765a7a793
permissions
-rw-r--r--

configure script updated

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace UI
{  
    public class Application
    {
        private static Application instance;

        private System.Windows.Application application;

        private Thread thread;
        private Queue<Action> queue = new Queue<Action>();
        private object sync = new object();
        private object result = new object();

        private Boolean Running = false;
        public String Name;
        
        private Application() : base()
        {
            thread = new Thread(() => Run());
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }

        public static Application GetInstance()
        {
            if (instance == null)
            {
                instance = new Application();
                GC.KeepAlive(instance);
            }
            return instance;
        }

        public Thread Start()
        {
            lock(sync)
            {
                queue.Enqueue(() => RunApplication());
                Monitor.Pulse(sync);
            }
            return thread;
        }

        private void RunApplication()
        {
            application = new System.Windows.Application();
            application.Run();
        }

        public void Run()
        {
            lock(sync)
            {
                for (;;)
                {
                    Monitor.Wait(sync);
                    Action action = queue.Dequeue();
                    action.Invoke();
                    lock (result)
                    {
                        Monitor.Pulse(result);
                    }
                }
            }
        }

        public T Exec<T>(Func<T> func)
        {
            ResultExec<T> e = new ResultExec<T>();
            e.Func = func;

            if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
            {
                e.Exec();
                return e.Result;
            }
            else
            {
                lock (sync)
                {
                    queue.Enqueue(() => e.Exec());
                    Monitor.Pulse(sync);
                }
                lock (result)
                {
                    Monitor.Wait(result);
                }

                return e.Result;
            }
        }

        public void Exec(Action action)
        {
            if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
            {
                action.Invoke();
            }
            else
            {
                lock (sync)
                {
                    queue.Enqueue(action);
                    Monitor.Pulse(sync);
                }
                lock (result)
                {
                    Monitor.Wait(result);
                }
            }
        }
    }

    public class ResultExec<T>
    {
        public T Result;
        public Func<T> Func;

        public void Exec()
        {
            Result = Func.Invoke();
        }
    }

    public class VoidExec
    {
        public Action Action;

        public void Exec()
        {
            Action.Invoke();
        }
    }
}

mercurial