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()、次のように、ラムダ式を使用する代わりに、イベントハンドラーを非ヌルに初期化することをお勧めします。

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

次に、nullチェックなしで呼び出すことができますTextParsed(...)。これにより、コードがわかりやすくなる可能性があります。

于 2008-11-06T14:20:22.077 に答える
1

個人的には、これはコードの全体的な構造としてかなり優れていると思います。論理ユニットを独自の操作に簡単に分離できます。また、サービスから通知することで、後で別のサービス エージェントをセットアップする必要がある場合に、将来的に優れた拡張性が得られます。

于 2008-11-03T16:14:41.427 に答える