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

相关文章
相关标签/搜索