3

2 つの方法があるとします。1 つは、リストボックスで選択されたインデックスの変更によってトリガーされるメソッドです。2 番目の方法は、すべてのテキスト ボックスをクリアし、リスト ボックスのインデックスを -1 に設定し、フォーカスを設定することで役立ちます。

質問:

メソッド 2 が実行され、コード中にリストボックスの選択されたインデックスが -1 に変更され、それによって最初のメソッドのイベント トリガーが設定されます。方法 2 はそれ自体の実行を停止し、プロセスをイベントに転送し、方法 1 が終了した後に作業に戻りますか? または、方法 2 はコードブロック全体を終了し、選択したインデックスが変更されたため、方法 1 に転送しますか?

4

5 に答える 5

8

最初のケース。

特にスレッドはシナリオに関与していないため、しばらくスレッドを除外しましょう。

プロパティとメソッドについて話していますが、その下にあるのはすべて単なる関数です。ある関数が別の関数を呼び出すと、プログラム内の制御は呼び出された関数に移ります。その関数の実行が終了すると、制御は呼び出されたポイントに戻ります。プログラムは、関数がより多くの関数をどれほど深く呼び出しても、どこに戻る必要があるかを自動的に覚えています。*

2 番目の関数がインデックスを設定するときに実際に起こることは、コンパイラがプロパティ セット操作を関数呼び出しに変換することです。(プロパティは、最終的には関数の「シンタックス シュガー」にすぎません。) その関数は、シナリオにとって重要ではない他の関数の束を呼び出しますが、そのうちの 1 つは「インデックス変更」イベント ハンドラーを呼び出す関数です。そのイベントに関連付けられたメソッドがあることを認識し、最初のメソッドを呼び出します。

最初のメソッドが実行され、終了すると、「インデックスが変更されたイベント ハンドラーを呼び出す」関数に戻ります。最終的に、それと他のすべての重要でない関数の実行が終了し (おそらく、さらに関数呼び出しを順番に行った後)、「インデックス プロパティの設定」関数が制御を 2 番目のメソッドに返します。

あなたの最初の提案がそれがどのように機能するかを自分自身に証明することができます. 最初のメソッドでメッセージ ボックスを表示し、2 番目のメソッドで index プロパティを設定したポイントの後に別のメッセージ ボックスを表示します。(別のメッセージを使用してください!) 最初のメッセージが表示され、メッセージ ボックスを閉じると 2 番目のメッセージが表示され、最初のメソッドの実行中に 2 番目のメソッドが実行を継続しなかったことが示されます。

*制限ありますが、プログラムにバグがない限り、ヒットすることはめったにありません。ネストされた関数呼び出しが多すぎると、スタック オーバーフローが発生します。

于 2009-02-20T01:53:12.467 に答える
1

マルチスレッドの状況がないと仮定すると、イベントはメソッドの実行が終了する前に発生します。これを確認したい場合は、提案した内容を.NET言語でコーディングし、生成されたIlを調べてください。これは、ILDASMまたはReflectorを使用して行うことができます。また、独自の反射アプリケーションを作成することもできます。ブランチを確認するには、ILの構文を十分に理解する必要がありますが、プログラミングの概念を理解している限り、それほど難しくはありません。

ロブはこれを「シンタックスシュガー」とラベル付けしましたが、これには多少同意します。これは実際にはコンパイラのトリックですが、一般的に使用されている「シンタックスシュガー」というラベルに該当すると思います。

于 2009-02-20T02:47:10.653 に答える
1

探索できる 3 番目の選択肢があります。同時に実行することもできます。あなたの質問を正しく理解できれば、メソッド 2 はインデックス変更イベントによってトリガーされます。C# Windows フォーム アプリケーションでは、この別のイベントは別の実行スレッドで発生します。

探索する概念: スレッド化。

これが知識の探求の出発点になることを願っています。

于 2009-02-20T01:16:28.250 に答える
0

問題の言語は c# であり、複数のスレッドをサポートする言語を持っていると思います。スレッドについて心配したくない場合 (ユーザー エクスペリエンスを考慮すると、これは悪い考えです)、GUI を 1 つのスレッドで実行し、コンポーネントが独自のスレッドを作成しない限り、同じ動作をすることができます (これは少し面倒です)。変だけど)。イベントの非同期 (並列) 実行を実現したい場合は、イベントを独自のスレッドでトリガーする必要があります。

あなたの質問に答えるには: 複数のスレッドを使用していない場合、イベントによってトリガーされたメソッドはキューに入れられます。これはまさに、一部のプログラムで GUI の応答が遅い場合に発生することです。

それが問題を解決し、別の新参者から歓迎されることを願っています:)

于 2009-02-20T01:15:55.737 に答える
0

私自身初心者ですので、参考になれば幸いです。Method2 が実行され、選択が変更されると Method1 が処理を実行し、次に Method2 が続行します。

その時点で Method1 を起動させたくない場合は、次のようにすることをお勧めします: (REALLY 疑似コード)

Method2(object sender, System.EventArgs e)
{
  //Unsubscribe Method1 from ListboxEvent
  Listbox.OnSelectionChange -= Method1;

  ... Stuff Method2 actually does ...

  Manualy call Method1 if you want it to fire

  //Subscribe Method1 from ListboxEvent
  Listbox.OnSelectionChange += Method1;
}

それはおそらく最適ではありません (そしておそらくいくつかのベストプラクティス...) が、より良い説明がないため、少なくとも検索に役立つ情報が少しあります. それが役に立てば幸い!

于 2009-02-20T01:43:16.967 に答える