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

发布于 2024-07-08 11:21:04 字数 2114 浏览 7 评论 0原文

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

I'm reading up on event-driven design. I am having trouble getting my head around some of it in practice. I'm considering using this for a windows service that monitors, parses, and handles information coming from a 3rd party TCP stream. Is the following a decent approach, or am I missing something?

My plan is to have a the main service be simply a container for events:

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);            
    }

    ...
}

Then, using MEF or similar, I'll register "ServiceAgent" instances, which simply handle and/or raise events, optionally doing so on a background thread. For example:

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);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

飘逸的'云 2024-07-15 11:21:04

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

I personally think that it is a fairly good overall structue to your code, it easily separates logical units into their own operations, and by notifying out of the service it allows you good expandability in the future if you need to setup different serviceagents later.

喜你已久 2024-07-15 11:21:04

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

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

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

If the Raise() method is there only to simplify the null checking, you might want to initialize event handlers to non-null instead using a lambda expression, like so:

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

Then you could call TextParsed(...) without the null check, which might make the code easier to follow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文