view Implab/TaskController.cs @ 129:471f596b2603 v2

Added SharedLock to synchronization routines
author cin
date Thu, 29 Jan 2015 18:31:06 +0300
parents c761fc982e1d
children f75cfa58e3d4
line wrap: on
line source

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

namespace Implab
{
    /// <summary>
    /// This class allows to interact with asyncronuos task.
    /// </summary>
    /// <remarks>
    /// Members of this object are thread safe.
    /// </remarks>
    public class TaskController: IProgressNotifier, ITaskController
    {
        readonly object m_lock;
        string m_message;

        float m_current;
        float m_max;

        bool m_cancelled;

        public event EventHandler Cancelled;
        public event EventHandler<ValueEventArgs<string>> MessageUpdated;
        public event EventHandler<ValueEventArgs<float>> ProgressUpdated;
        public event EventHandler<ProgressInitEventArgs> ProgressInit;

        public TaskController()
        {
            m_lock = new Object();
        }

        public string Message
        {
            get
            {
                lock (m_lock)
                    return m_message;
            }
            set
            {
                lock (m_lock)
                {
                    m_message = value;
                    OnMessageUpdated();
                }
            }
        }

        public float CurrentProgress
        {
            get
            {
                lock (m_lock)
                    return m_current;
            }
            set
            {
                lock (m_lock)
                {
                    var prev = m_current;
                    m_current = value;
                    if (m_current >= m_max)
                        m_current = m_max;
                    if (m_current != prev)
                        OnProgressUpdated();
                }
            }
        }

        public void InitProgress(float current, float max, string message)
        {
            if (max < 0)
                throw new ArgumentOutOfRangeException("max");
            if (current < 0 || current > max)
                throw new ArgumentOutOfRangeException("current");

            lock(m_lock) {
                m_current = current;
                m_max = max;
                m_message = message;
                OnProgressInit();
            }
        }

        public bool IsCancelled {
            get {
                lock (m_lock)
                    return m_cancelled;
            }
        }

        public void Cancel() {
            lock (m_lock) {
                if (!m_cancelled)
                    m_cancelled = true;
            }
        }

        protected virtual void OnCancelled() {
            var temp = Cancelled;
            if (temp != null) {
                temp(this,new EventArgs());
            }
        }

        protected virtual void OnMessageUpdated()
        {
            var temp = MessageUpdated;
            if (temp != null)
            {
                temp(this, new ValueEventArgs<string>(m_message));
            }
        }

        protected virtual void OnProgressUpdated()
        {
            var temp = ProgressUpdated;
            if (temp != null)
            {
                temp(this,new ValueEventArgs<float>(m_current));
            }
        }

        protected virtual void OnProgressInit()
        {
            var temp = ProgressInit;
            if (temp != null)
            {
                temp(this, new ProgressInitEventArgs(m_current,m_max, m_message));
            }
        }
    }
}