对于Windows服务,这是一个不错的事件驱动方法吗?

时间:2008-11-03 15:39:11

标签: event-driven-design

我正在阅读事件驱动设计。我在实践中无法理解其中的一些问题。我正在考虑将此用于监视,解析和处理来自第三方TCP流的信息的Windows服务。以下是一个体面的方法,还是我错过了什么?

我的计划是让主要服务只是事件的容器:

public class MyService
{                      

    public void RegisterAgent(ServiceAgent agent)
    {
        Log("Initializing agent " + agent);
        agent.Initialize(this);
        Log("Done intializing agent " + agent);
    }

    public void Log(string messageText)
    {
        OnSimpleLogEventLogged(this, new SimpleLogEventArgs(messageText));
    }

    protected void Raise<T>(EventHandler<T> eventHandler, object sender, T args) where T : EventArgs
    {
        var handler = eventHandler;
        if (handler == null) return;                       
        handler(sender, args);

    }

    public event EventHandler<SimpleLogEventArgs> SimpleLogEventLogged;
    protected void OnSimpleLogEventLogged(object sender, SimpleLogEventArgs args)
    {
        Raise(SimpleLogEventLogged, sender, args);
    }

    public event EventHandler<TextRecievedEventArgs > TextRecieved;
    public void OnTextRecieved(object sender, TextRecievedEventArgs args)
    {
        Raise(TextRecieved, sender, args);            
    }

    public event EventHandler<TextParsedEventArgs> TextParsed;
    public void OnTextParsed(object sender, TextParsedEventArgs args)
    {
        Raise(TextParsed, sender, args);            
    }

    ...
}

然后,使用MEF或类似方法,我将注册“ServiceAgent”实例,它只是处理和/或引发事件,可选地在后台线程上执行。例如:

public class TextParsingAgent : ServiceAgent
{

    public override void Initialize(MyService service)
    {
        service.TextRecieved += TextRecieved;
        base.Initialize(service);
    }

    void TextRecieved(object sender, TextRecievedEventArgs e)
    {
        ThreadPool.QueueUserWorkItem(TextRecievedAsync, e);
    }

    private void TextRecieved(object state)
    {
        var e = (TextRecievedEventArgs)state;
        //TODO:Parse text into something meaningful and store in textParseEventArgs
        service.OnTextParsed(textParseEventArgs);
    }
}

2 个答案:

答案 0 :(得分:1)

我个人认为它对您的代码来说是一个相当不错的整体结构,它可以轻松地将逻辑单元分离到自己的操作中,如果您需要设置不同的服务代理,通过通知服务它可以在将来实现良好的可扩展性后面。

答案 1 :(得分:1)

如果Raise()方法仅用于简化空检查,则可能需要使用lambda表达式将事件处理程序初始化为非null,如下所示:

public event EventHandler<TextParsedEventArgs> TextParsed = (sender, e) => { };

然后你可以在没有空检查的情况下调用TextParsed(...),这可能会使代码更容易理解。