3

我正在阅读事件驱动设计。在实践中,我很难理解其中的一些内容。我正在考虑将其用于监视、解析和处理来自第 3 方 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);
    }
}
4

2 回答 2

1

如果该Raise()方法只是为了简化空值检查,您可能希望将事件处理程序初始化为非空值,而不是使用 lambda 表达式,如下所示:

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

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

于 2008-11-06T14:20:22.077 回答
1

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

于 2008-11-03T16:14:41.427 回答