3

私は現在、ユーザーが特定のワイヤレスネットワークに接続するときに、特定のネットワークリソースに対してユーザーを自動的に認証するC#アプリケーションを構築しています。

現在、私はManaged Wifi APIを使用して、ユーザーがワイヤレスネットワークに接続/切断するタイミングを検出しています。私はイベントハンドラーを持っているので、これらのアクティビティのいずれかが発生すると、ワイヤレス接続の現在の状態を検査するために私のメソッドの1つが呼び出されます。

アプリケーションの状態を管理するために、アプリケーションの状態を変更するために必要な操作を実行する「コンダクター」と呼ばれる別のクラスがあります。たとえば、ワイヤレスカードが正しいネットワークに接続する場合、コンダクタはシステム状態を「監視」から「認証」に変更する必要があります。認証が成功した場合、コンダクターは状態を「接続済み」に変更する必要があります。切断すると再び「監視」状態になり、認証エラーにより「エラー」状態になります。これらの状態の変化(ユーザーが要求した場合)はTrayIcon通知をもたらす可能性があるため、ユーザーはそれらが認証されていることを認識します。

私の現在のアイデアは、ワイヤレスの現在の状態を検査するために使用されるメソッドを使用して、状態マネージャー内の「認証」または「切断」メソッドを呼び出すことを含みます。ただし、これがイベントハンドラーの適切な使用法であるかどうかはわかりません。代わりに、フラグを設定するか、何らかの形式のIPCを介して別のスレッドにメッセージを送信して認証/切断プロセスを開始する必要がありますか?

イベントハンドラーが接続/切断を要求できることに加えて、ユーザーはトレイアイコンを介してそれを実行することもできます。結果として、これらのバックグラウンド操作がトレイのユーザーとの対話をブロックしていないことを確認する必要があります。

いつでも1つのコンポーネントのみがシステム状態の変更を要求できるはずなので、同時状態変更を防ぐためにミューテックスを使用する必要があります。ただし、これらの残りのコンポーネントをどのように同期する必要があるかは、私には少し謎です。

私が読むべきアドバイスや文献はすべて適用されます。私はC#言語の正式なトレーニングを受けていないので、何かを間違えた場合はお詫び申し上げます。

編集:最も重要なのは、イベントが別のスレッドとして実行されることを確認したいので、メインUIをブロックできないことです。さらに、イベントハンドラーがイベントにサブスクライブしている場合、イベントを並列ではなくシリアルに処理することを確認したいと思います(したがって、最初の接続イベントが処理される前にユーザーが接続および切断した場合、2つの状態変化は発生しません同時に発生します)。

4

5 に答える 5

1

オプションとして、代替...

私があなただったら、とにかく新しく始めるので、
Rx Reactive Extensionsを真剣に検討します

イベントとイベントベースのプログラミングを完全に新鮮な視点で見ることができ、あなたが扱っていること (同期、スレッドの処理、イベントの結合、停止、開始などを含む) を正確に処理するのに役立ちます。

最初に学ぶのは少し「急なカーブ」かもしれませんが、繰り返しますが、それだけの価値があるかもしれません。

お役に立てれば、

于 2012-04-06T21:42:11.060 に答える
1

私が読むべきアドバイスや文献があれば、感謝します。私は C# 言語の正式なトレーニングを受けていません。

それはいくつかのことを説明しています。:)
スレッド、イベント処理、およびシステム トレイ アイコン/インターフェイスの作成について調べます。

次の点に注意することが重要です。

  • イベントは、呼び出し元と同じスレッドで処理されます。イベントの処理によって GUI がロックされないようにする場合は、ボタンで作業を別のスレッドに移動させる必要があります。
  • イベントが発生すると、リスト内のすべてのメソッドに適切な引数が渡されます。これは、1 つのメソッドを呼び出して、他のすべてのメソッドを呼び出すのとほとんど同じです (EventFired の例を参照)。イベントの目的は、メソッドを呼び出すことではなく、コードがコンパイルされたときに認識されない可能性があるメソッドを呼び出すことです (ボタン コントロールのクリック イベントは、コントロールがライブラリにある場合には認識されません)。たとえば、コンパイルされます)。つまり、イベントを使用する代わりにメソッドを呼び出すことができれば、そうすることができます。

    void EventFired(int arg1, object arg2)
    {
        subscribedMethod1(arg1, arg2);
        SubscribedMethod2(arg1, arg2);
        SubscribedMethod3(arg1, arg2);
        SubscribedMethod4(arg1, arg2);
        SubscribedMethod5(arg1, arg2);
        SubscribedMethod6(arg1, arg2);
        SubscribedMethod7(arg1, arg2);
    }
    
  • ユーザー インターフェイスがロックされないようにしたい場合は、別のスレッドで作業を行ってください。ただし、ユーザー インターフェイス要素 (フォーム、ボタン、グリッド、ラベルなど) には、ホスト スレッドからしかアクセスできないことに注意してください。control.Invoke メソッドを使用して、スレッドでメソッドを呼び出します。

  • インターフェイスからオプションを削除することは、レースウェイ状態 (既に実行されているときにユーザーが接続/切断を開始する) を防ぐ良い方法ではありません。これは、ユーザー インターフェイスが別のスレッド上にあり、同期が取れなくなる可能性があるためです (処理に時間がかかるため)。スレッドを分けて同期します)。この問題を解決するには多くの方法がありますが、スレッド化に慣れていない人にとって最も簡単な方法は、値をロックすることです。このようにして、.NET は一度に 1 つのスレッドだけが設定を変更できるようにします。更新が行われていることをユーザーが認識できるように、ユーザー インターフェイスを更新する必要があります。

あなたの一般的なデザインはうまく聞こえます。2 ~ 3 個のスレッド (ユーザー インターフェイス (トレイ アイコン) 用に 1 つ、新しいネットワーク接続のチェック用に 1 つ、インターネット接続をチェックする 1 つ (接続チェックとマージ可能)) を使用できます。

これがお役に立てば幸いです。さらに必要な場合はお知らせください (または回答を受け入れます)。

于 2012-04-06T21:12:30.017 に答える
0

には、あなたはプロジェクトをオーバーエンジニアリングしようとしているようです。基本的に、イベントを実装しCommander、メインアプリケーションでサブスクライブする必要があります。あれは。

常に1つのコンポーネントが変更を加えることができ、複数のコンポーネントを持つことができる場合、あなたがMutex指摘したような同期メカニズムを使用することは完全に有効な選択です.

お役に立てれば。

于 2012-04-06T20:45:05.193 に答える
0

常に 1 つの状態変更を保留にしたい場合は、リッスンしている外部イベントのイベント ハンドラーが実行中にロックを保持するようにするのがおそらく最善です。これにより、アプリの状態が変更されないことが保証されるため、プログラミングが簡単になります。この特定のケースでは、別のスレッドは必要ありません。

アプリケーションの現在の状態とターゲットの状態を区別する必要があります。ユーザーは、ターゲットの状態 (「接続済み」、「切断済み」) を指示します。実際の状態は異なる場合があります。例: ユーザーは切断を望んでいますが、実際の状態は認証中です。認証手順が完了すると、ステート マシンはターゲットの状態を調べる必要があります。

targetState == connected => set current state to connected
targetState == disconnected => begin to disconnect and set state to disconnecting

実際の状態と目標の状態を分離することで、ユーザーはいつでも考えを変えることができ、ステート マシンは目的の状態に向けて操縦できます。

于 2012-04-06T20:45:32.537 に答える
0

アプリの (提案された) 構造全体を見ずに正確な答えを出すことは困難です。しかし、一般的には、そのようなことにはイベント ハンドラーを使用してもかまいませんが、実際の実装を別のメソッドに移動して、他の場所からより簡単にトリガーできるようにすることをお勧めします。

「接続」ボタンを無効にすることについてのコメントは、私には正しく聞こえますが、他の形式の同期も必要になる可能性は十分に考えられます。ただし、アプリをマルチスレッド化する必要がない場合は、そのためだけに複数のスレッドを導入することは避けたいと思います。その場合は、Task Parallel Libraryの一部として含まれている新しい Task API を調べてください。彼らはその多くをかなりうまく抽象化しています。

また、この問題について考えすぎないというコメントもよく理解されています。私があなたの立場で、新しい言語を始めたばかりの場合、最初からアーキテクチャを正しく理解しようとすることは避けます。掘り下げて、既に入手しているコグニティブ ツールセットを使用して開発します。さらに調べていくうちに、「ああ、くそ、これはそれを行うためのはるかに優れた方法だ」ことがわかります。そして、行ってそのようにします。リファクタリングはあなたの友達です。

于 2012-04-06T20:46:35.080 に答える