首页 > 代码库 > C# 关于PipeLine管道的用法
C# 关于PipeLine管道的用法
pipeline类似于工厂加工,开始给一堆的零件,通过各个管道之后,从最后出口出来之后就是一件成品。管道链类似的责任。的主要区别是,链,每个“链接”传递到下一个,直到人知道如何处理它,那么这个过程停止。在管道,传递给每一个链的链接和潜在的修改通过。这就是“管道和过滤器”发挥作用,因为一个链接可以过滤管可能会增加其他链接。
代码如下:
中间过程的接口:
一个上下文的结构:知道自己的上一个和下一个管道
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;
}
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);
}
}
比如第一个管道:
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);
}
}
C# 关于PipeLine管道的用法