Это достойный Event-Driven подход для службы Windows? - PullRequest
3 голосов
/ 03 ноября 2008

Я читаю на дизайн, управляемый событиями. У меня возникают проблемы с тем, чтобы разобраться с этим на практике. Я рассматриваю возможность использования этого для службы Windows, которая отслеживает, анализирует и обрабатывает информацию, поступающую из стороннего потока TCP. Является ли следующий подход достойным, или я что-то упустил?

Мой план состоит в том, чтобы основной сервис был просто контейнером для событий:

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 ]

1 голос
/ 06 ноября 2008

Если метод Raise() существует только для упрощения проверки нуля, вы можете инициализировать обработчики событий ненулевыми вместо использования лямбда-выражения, например так:

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

Тогда вы могли бы позвонить TextParsed(...) без проверки нуля, что может облегчить выполнение кода.

1 голос
/ 03 ноября 2008

Лично я считаю, что это довольно хорошая общая структура для вашего кода, она легко разделяет логические блоки на их собственные операции, и, уведомляя об отказе от сервиса, это дает вам хорошую расширяемость в будущем, если вам нужно настроить различные сервисные агенты позже.

...