0

シナリオがあります。Windowsフォームに表示されるユーザーIDのリストがあります。ユーザー ID の 1 つをクリックするとすぐに、DB からユーザーの詳細を取得します。アプリケーションの応答性を維持するために、リストボックスの選択変更イベントで、新しい BackgroundWorker(BW) オブジェクトを作成して DB にアクセスします。ステータス バーに「ユーザー 'abc' を検索しています...」と表示されます。

ここで、ユーザーが矢印キーを使用して (4 ~ 5 回) ユーザー ID 間を移動すると、上記の設計により、要求を行うために複数の BW オブジェクトが作成されました。しかし、最終的に特定のユーザー (リストビューでユーザーが現在選択されているユーザーではない可能性があります) のデータが戻ってくると、非同期呼び出しだったため、ステータスバーにすべてのユーザーが表示されます。

私がやりたいのは、最後のユーザーだけの詳細を取得したいということです。それまでは「検索中のユーザー...」のみを表示したい。

この場合の解決策を教えてください...

4

4 に答える 4

2

ユーザーがユーザーを切り替えると、現在実行中のワーカー プロセスをキャンセルできます (実行中であることを確認してください)。私はそれがあなたが求めているものを達成すると信じています.

于 2009-07-15T17:57:57.723 に答える
1

バックグラウンドワーカーを開始する前に、1〜2秒待ってみませんか?

ユーザーがユーザーIDをクリックしたら、1秒間隔でタイマーを開始し、その1秒後にBackgroundWorkerを開始します。ユーザーが別のユーザーIDをクリックした場合は、タイマーをリセットしてください。このように、ユーザーがさまざまなユーザーIDをすばやく連続してクリックし続けると、何もしなくなります。ユーザーが休憩をとったら、バックグラウンドワーカーを開始します。

于 2009-07-15T20:30:35.777 に答える
0

1 つのオプションは、ユーザー ID を含むフォームに文字列フィールドを保持することです。バックグラウンド ワーカーで、DB にアクセスした後、このフィールドが渡されたユーザー ID と同じであることを確認し、EDIT : 異なる場合は結果を作成しnullます。 ロックする必要がないように、クラスのメソッドを使用してフィールドを操作します。Interlocked それは間違っている; 参照型は、アトミックに読み書きできますInterlocked

2番目の編集: バックグラウンド ワーカーから元のユーザー ID を結果と共に返し、それが Completed ハンドラーでクリックされた最新のものであることを確認することもできます。

または、すべての BackgroundWorker への参照を保持している場合は、それらのキャンセル サポートを使用できます。

于 2009-07-15T17:59:18.110 に答える
-1

以前にBackgroundWorkersをキャンセルするためにこれを使用しましたが、うまく機能しました。

    public void cancelWorker( BackgroundWorker worker )
    {
        if (worker != null)
        {
            if (worker.IsBusy)
            {
                worker.CancelAsync();

                while (worker.IsBusy)
                {
                    Application.DoEvents();
                }
            }
        }
    }

Application.DoEvents();の使用についての論争を聞いたことがあります。しかし、Thread.sleepなどを使用すると、無限ループに問題が発生しました。

ある種のポーリングを使用して、backgroundWorkersが互いにぶつからないようにすることができます。特に、コールバックが別のスレッドでUIのようなものを呼び出して、実際に競合状態を引き起こす可能性がある場合はそうです。

于 2009-07-15T18:09:53.283 に答える