C# 關於PipeLine管道的用法

      pipeline相似於工廠加工,開始給一堆的零件,經過各個管道以後,從最後出口出來以後就是一件成品。管道鏈相似的責任。的主要區別是,鏈,每一個「連接」傳遞到下一個,直到人知道如何處理它,那麼這個過程中止。在管道,傳遞給每個鏈的連接和潛在的修改經過。這就是「管道和過濾器」發揮做用,由於一個連接能夠過濾管可能會增長其餘連接。promise

       代碼以下:ide

中間過程的接口:this

 

一個上下文的結構:知道本身的上一個和下一個管道url

 

 public class HandlerContext
    {
        private IEventHandler _handler;

        protected HandlerContext()
            : this(null)
        {
        }

        public HandlerContext(IEventHandler handler)
        {
            _handler = handler;
            Next =null;
            Prev = null;
        }

        public virtual IEventHandler Handler
        {
            get { return _handler; }
        }

        public static Task<object> Invoke(HandlerContext ctx, object data, TaskCompletionSource<Object> tcs = null)
        {
            var promise = tcs ?? new TaskCompletionSource<object>();
            if (ctx != null)
            {
                ctx.Handler.Process(ctx, data, promise);
            }
            return promise.Task;
        }

        public Task<object> FireProcess(object data)
        {
            var next = this.Next;
            return Invoke(next, data);
        }

        public Task<object> FireProcess(object data, TaskCompletionSource<Object> tcs)
        {
            var next = this.Next;
            return Invoke(next, data, tcs);
        }

        internal HandlerContext Next;
        internal HandlerContext Prev;
    }code

 

PipeLine類:做用是添加中間的管道接口

 class AlarmPipeline
    {
        private readonly HandlerContext _head;
        private readonly HandlerContext _tail;

        public AlarmPipeline()
        {
            _head = new Decoder();
            _tail = new Renderer();
            _head.Next = _tail;
            _tail.Prev = _head;
        }

        public void AddLast(IEventHandler handler)
        {
            var newcontext = new HandlerContext(handler);
            var prev = _tail.Prev;
            prev.Next = newcontext;
            newcontext.Prev = prev;
            _tail.Prev = newcontext;
        }

        public void AddFirst(IEventHandler handler)
        {
            var newcontext = new HandlerContext(handler);
            var next = _head.Next;
            _head.Next = newcontext;
            newcontext.Next = next;
            newcontext.Prev = _head;
        }

        public bool AddAfter(IEventHandler prev, IEventHandler handler)
        {
            HandlerContext ctx = null;
            var cur = _head;
            while (cur != null)
            {
                if (cur.Handler == prev)
                {
                    ctx = cur;
                    break;
                }
                cur = cur.Next;
            }

            if (ctx == null)
                return false;

            var newcontext = new HandlerContext(handler);
            var next = ctx.Next;
            ctx.Next = newcontext;
            newcontext.Next = next;
            newcontext.Prev = ctx;
            next.Prev = newcontext;
            return true;
        }

        public void Remove(IEventHandler handler)
        {
            if (handler == null)
                return;

            var low = _head.Next;
            var high = _tail.Prev;
            do
            {
                if (low != null)
                {
                    if (low.Handler == handler)
                    {
                        _DoRemove(low);
                    }
                    low = low.Next;
                }

                if (high != null)
                {
                    if (high.Handler == handler)
                    {
                        _DoRemove(high);
                    }
                    high = high.Prev;
                }
            } while (low != high);
        }

        public void RemoveFirst()
        {
            if (_head.Next == null) return;
            this.Remove(_head.Next.Handler);
        }

        public void RemoveLast()
        {
            if (_tail.Prev == null) return;
            this.Remove(_tail.Prev.Handler);
        }

        private void _DoRemove(HandlerContext ctx)
        {
            var prev = ctx.Prev;
            var next = ctx.Next;
            prev.Next = next;
            next.Prev = prev;
        }

        public Task<object> Process(object data)
        {
            return HandlerContext.Invoke(_head, data);
        }

    }ip

 

好比第一個管道:get

 class Decoder : HandlerContext, IEventHandler
    {
        public override IEventHandler Handler
        {
            get
            {
                return this;
            }
        }

        public void Process(HandlerContext context, object data, TaskCompletionSource<object> tcs)
        {
            string url = (string)data;
            
            var provider = new Provider(url);
            provider.Load();

            context.FireProcess(alarmdata, tcs);
        }
    }string

相關文章
相關標籤/搜索