iT邦幫忙

DAY 10
2

c#應用系列 第 10

C#應用(10)設計模式

*參考資料
** 設計模式

回目錄
以下還沒想到可以用在那裡?

*檔案 Command.cs

using System;
using System.Collections.Generic;

namespace ObjectOriented.DesignPatterns
{
    public interface Command<TObj, TArgs>
    {
        public abstract void ExecCommand(TObj target, TArgs args);
    }

    abstract class Executor<TKey, TObj, TArgs>
    {
        private Dictionary<TKey, Command<TObj, TArgs>> buffer = new Dictionary<TKey, Command<TObj, TArgs>>();

        protected abstract void Init();
        protected abstract void OnError(Command<TObj, TArgs> cmd, Exception ex);

        public void Exec(TObj target, TKey key, TArgs args)
        {
            Command<TObj, TArgs> cmd = null;
            try
            {
                cmd = buffer[key];
                cmd.ExecCommand(target, args);
            }
            catch (Exception ex)
            {
                OnError(cmd, ex);
            }
        }
    }
}

*檔案 ObjectPool.cs

using System;
using System.Threading;
using System.Collections.Generic;

namespace ObjectOriented.DesignPatterns
{
    abstract class ObjectPool<TValue> where TValue : class
    {
        private Queue<TValue> buffer = new Queue<TValue>();
        private SpinLock _spinLock = new SpinLock();
        private bool lockTaken = false;

        public ObjectPool(int capacity = 1)
        {
            for (int i=0; i<capacity; i++)
                buffer.Enqueue(CreateObject());
        }

        protected abstract TValue CreateObject();

        public TValue GetObject()
        {
            try
            {
                _spinLock.Enter(ref lockTaken);
                if (buffer.Count != 0)
                {
                    return buffer.Dequeue();
                }
                else
                {
                    return CreateObject();
                }
            }
            finally
            {
                if (lockTaken) _spinLock.Exit();
            }           
        }

        public void Release(TValue obj)
        {
            try
            {
                _spinLock.Enter(ref lockTaken);
                buffer.Enqueue(obj);
            }
            finally
            {
                if (lockTaken) _spinLock.Exit();
            }
        }
    }
}

*檔案 ShareObjec.cs

using System;
using System.Collections.Generic;
using System.Threading;

namespace ObjectOriented.DesignPatterns
{
    abstract class ShareObject<TKey>
    {
        public TKey ID { get; set; }
        private int refCount = 0;

        private ShareObject() 
        { 
        }

        public int AddRef() 
        {
            return  Interlocked.Increment(ref refCount);
        }

        public int Release() 
        {
            return Interlocked.Decrement(ref refCount);
        }
    }

    abstract class ShareObjectPool<TKey, TValue> where TValue : class
    {
        private Dictionary<TKey, TValue> buffer = new Dictionary<TKey, TValue>();
        private SpinLock _spinLock = new SpinLock();
        private bool lockTaken = false;

        private ShareObjectPool()
        {
        }

        protected abstract TValue CreateObject(TKey ID);

        public TValue GetObject(TKey ID)
        {
            try
            {
                _spinLock.Enter(ref lockTaken);
                TValue result = null;
                if (buffer.TryGetValue(ID, out result))
                {
                    (result as ShareObject<TKey>).AddRef();
                    return result;
                }
                else
                {
                    result = CreateObject(ID);
                    buffer.Add(ID, result);
                    return result;
                }
            }
            finally
            {
                if (lockTaken) _spinLock.Exit();
            }           
        }

        public void Release(TValue obj)
        {
            try
            {
                _spinLock.Enter(ref lockTaken);
                ShareObject<TKey> obj2 = obj as ShareObject<TKey>;
                if (obj2.Release() == 0)
                {
                    buffer.Remove(obj2.ID);
                }
            }
            finally
            {
                if (lockTaken) _spinLock.Exit();
            }
        }
    }
}

上一篇
C#應用(9)自訂HtmlHelperExtensions
下一篇
C#應用(11)ActiveX
系列文
c#應用13

2 則留言

0
0
Ethan Jhuang
iT邦研究生 3 級 ‧ 2013-09-26 14:22:49

請問一下...
一天念4小時的話
大概多久能到Player大神這種等級阿...
驚

我要留言

立即登入留言