.NET – Command Queue 구현

즐겨쓰는 Command Queue 방식.

Polling 하는 Thread를 따로 두지 않는다.

Command Interface

interface IExecutable
{
    void Execute();
}

Command Executer

/// 
/// The executer with queue.
/// 
internal class ExecuterWithQueue
{
    /// 
    ///   The is executing.
    /// 
    private bool isExecuting;

    /// 
    ///   The queue.
    /// 
    private ConcurrentQueue queue;

    /// 
    /// Gets Queue.
    /// 
    private ConcurrentQueue Queue
    {
        get
        {
            if (this.queue == null)
            {
                this.queue = new ConcurrentQueue();

                Logger.Write("Queue", string.Format("{0} Queue Created.", "IExecutable"), TraceEventType.Verbose);
            }

            return this.queue;
        }
    }

    /// 
    /// The enqueue.
    /// 
    /// 
    /// The command.
    /// 
    public void Enqueue(IExecutable command)
    {
        Queue.Enqueue(command);

        Logger.Write("Enqueue", string.Format("{0} Queue length : {1}", "IExecutable", Queue.Count), TraceEventType.Verbose);

        DequeueAndExecute();
    }

    /// 
    /// The dequeue and execute.
    /// 
    private void DequeueAndExecute()
    {
        if (this.isExecuting)
        {
            return;
        }

        IExecutable command;

        if (!Queue.TryDequeue(out command))
        {
            return;
        }

        try
        {
            this.isExecuting = true;

            command.Execute();
        }
        catch (Exception ex)
        {
            Logger.Write(ex);
        }
        finally
        {
            this.isExecuting = false;

            DequeueAndExecute();
        }
    }
}

비동기 작업 큐

internal delegate void AsyncJob(Action callback);

/// 
///   The Async job queue.
/// 
internal class AsyncJobQueue
{
    /// 
    ///   The is executing.
    /// 
    private bool _isExecuting;

    /// 
    ///   The queue.
    /// 
    private ConcurrentQueue _jobQueue;

    /// 
    ///   Gets Queue.
    /// 
    private ConcurrentQueue JobQueue
    {
        get
        {
            if (_jobQueue == null)
            {
                _jobQueue = new ConcurrentQueue();

                Console.WriteLine("{0} Queue Created.", "IExecutable");
            }

            return _jobQueue;
        }
    }

    /// 
    ///   The enqueue.
    /// 
    ///  The job. 
    public void Enqueue(AsyncJob job)
    {
        JobQueue.Enqueue(job);

        DequeueAndExecute();
    }

    /// 
    ///   The dequeue and execute.
    /// 
    private void DequeueAndExecute()
    {
        if (_isExecuting)
        {
            return;
        }

        AsyncJob job;

        if (!JobQueue.TryDequeue(out job))
        {
            return;
        }

        _isExecuting = true;

        ThreadPool.QueueUserWorkItem(j => ((AsyncJob) j)(Callback), job);
    }

    /// 
    ///   Job finished callback
    /// 
    public void Callback()
    {
        _isExecuting = false;
        DequeueAndExecute();
    }
}

답글 남기기

이메일 주소는 공개되지 않습니다.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> 

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.