4

私は WinForms アプリに取り組んでおり、その中にユーザー コントロールがあります。ユーザー コントロール内のボタンは、他のコードによって処理されるフォームまでのイベントを発生させます。ボタンの 1 つは、同時に実行すると問題を引き起こすいくつかのプロセスを開始します。状態を管理するためのロジックがコードに含まれているため、通常、プロセスが既に実行されている場合、ユーザーはプロセスを実行できません。ただし、ユーザーがボタンをダブルクリックすると、プロセスが 2 回開始されるので、それを防ぐのは困難です。

これを処理する最善の方法は何ですか?

クリックイベントでボタンを無効にすることから始めましたが、最初のクリックでボタンが無効になる前に2番目のクリックが発生しました。コードで他のフラグを設定しても、キャッチされませんでした。

イベントを発生させるコードに何らかの同期ロックを追加することを検討していますが、より良いアイデアがあるかどうか疑問に思っています。

このプロジェクトはほぼ完了しているので、アプリの根本的な書き直し (複合アプリケーション ブロックの実装など) を含まない回答を探していますが、次のプロジェクトで使用できるので、それらのアイデアも自由に投稿してください。 .

4

8 に答える 8

5

ボタンの無効化やその他のロックは、イベント ハンドラーで最初に行うことを確認してください。最初の命令が発火する前に 2 つのクリック イベントをキューに入れることができれば、非常に驚​​きますが、他のアプリで行き詰まっている非常に遅いコンピューターを使用している場合は、それが可能であると思います。

その場合はフラグを使用してください。

private bool runningExclusiveProcess = false;

public void onClickHandler(object sender, EventArgs e)
{
    if (!runningExclusiveProcess)
    {
        runningExclusiveProcess = true;
        myButton.Enabled = false;

        // Do super secret stuff here

        // If your task is synchronous, then undo your flag here:
        runningExclusiveProcess = false;
        myButton.Enabled = true;
    }
}

// Otherwise, if your task is asynchronous with a callback, then undo your flag here:
public void taskCompletedCallback()
{
    runningExclusiveProcess = false;
    myButton.Enabled = true;
}

それでも 2 回のクリックでそのようなものを取得できる場合は、誤って doubleClick イベントにサブスクライブしていないか、または何かおかしなことが起こっていないかを確認してください。

于 2008-10-31T22:28:41.953 に答える
3

イベントを2回処理していますか?

ボタンを無効にする前に 2 回目のクリックが行われていることを読んで、非常に驚​​いていますイベントを 2 回接続していないことを確認してください。以前、たまたまやったことがあります。その後、ほぼ瞬時に 2 つのイベントを取得します。

于 2008-11-01T00:17:32.060 に答える
2

そのボタンの無効化フラグは、ボタン イベント ハンドラーが完了するまで設定されず、追加のクリックは最初のクリックの後に Windows メッセージ キューに入れられます。ボタン イベント ハンドラーがすばやく完了して、UI スレッドが解放されるようにします。これを行うにはいくつかの方法がありますが、いずれもスレッドを作成するか、ワーカー スレッドを準備して AutoResetEvent を待機する必要があります。

于 2008-10-31T22:23:49.437 に答える
0

クリックしたらすぐにボタンを無効にします。そのため、イベントを 2 回処理することはできません。イベントが処理されるとすぐに、ボタンを再度有効にすることができます。

于 2008-11-04T12:09:46.413 に答える
0

ひょっとして、ボタンにアイコンをつけていませんか?コードを使用して一度に 2 つのプロセスを実行しないようにしてください。ただし、ボタンの外観と動作が従来のコマンド ボタン (長方形、テキスト ラベルのみ、「隆起した」表面で、クリック)。ちょっとした考え。

于 2008-11-03T12:27:05.677 に答える
0

せいぜい逸話的であれば、チェックされた答えは近いです。初心者にとっては、コードが多すぎて意味がありません。タイマーとスレッドの使用に関する記事を書きましたが、コード例は非常に理解しやすいものです。それを読んで、タスク プロセスを新しいスレッドで実行することにより、上記の例のフラグを設定できるかどうかを確認してください。

http://www.robault.com/category/Threading.aspx

于 2009-06-28T20:11:28.800 に答える
-1

ユーザーが最初にボタンをクリックした後、タスクを開始する前にボタンを無効にします。タスクが完了したら、ボタンを再度有効にします。

于 2008-10-31T22:18:02.927 に答える
-4

クリックイベントでボタンを無効にすることから始めましたが、最初のクリックでボタンが無効になる前に2番目のクリックが発生しました。コードで他のフラグを設定しても、キャッチされませんでした。

WinForms は本質的にシングルスレッドであるため、最初の処理が完了する前に 2 回目のクリックが発生することはありません (新しいスレッドや BackgroundWorkers などを使用している場合を除く)。

あなたの問題を説明するサンプルを見せてもらえますか?

于 2008-11-04T12:15:13.327 に答える