1

ブロッキングリソースを使用するメソッドに複数のクラスを処理するための最良の方法を理解しようとしています。

目標

を使用するメソッドへの複数の呼び出しを許可しますDataReader。この最初の呼び出しが進行中の間、メソッドが終了するまで残りの呼び出し (存在する場合) を保留にします。

このメソッドの実行が終了したら、最初の実行中に蓄積されたすべてのリクエストを破棄し、最後のリクエストの実行のみを許可する必要があります。

具体的には、実行が終了せず、その背後にある次の呼び出しで例外が発生するWindows.Formsオブジェクトで発生するイベントの繰り返しを扱っています。DataReader

この部分を設計するためのアイデアはありますか?

4

4 に答える 4

3

これで、イベント ハンドラーが作成され、時間の経過とともに繰り返しトリガーされます。以前に起動されたハンドラーがまだ実行されている場合は、何もしないでください。これは簡単です。ブール値の「isRunning」をインスタンス フィールドとして追加するだけで、それが true の場合は何もしません。変数へのアクセスを適切に同期するように注意してください。

private int isRunning = 0;//there is no bool overload for `Interlocked.Exchange`
private void button1_Click(object sender, EventArgs e)
{
    if (Interlocked.Exchange(ref isRunning, 1) == 0)
    {
        //do stuff

        isRunning = 0;
    }
    else
    {
        //another handler is already in progress; 
        //possibly display message to user, or do nothing, or whatever
    }
}

後続のイベント ハンドラーをスキップしたくないが、代わりに待機させて、一度に 1 つのみがクエリを実行するようにしたい場合は、次のように使用できますlock

private object key = new object();
private void button1_Click(object sender, EventArgs e)
{
    lock (key)
    {
        //do stuff
    }
}
于 2012-10-31T20:06:14.357 に答える
0

Java では、メソッドsynchronizedにマークを付けるだけですべてがうまくいきます。

C# では、さらに作業を行う必要があります。いくつかのオプションについては、この質問を参照してください。受け入れられた答えは、私にとって最良のものとは思えません。lock最初にキーワードを使用してみてください。

于 2012-10-31T20:04:21.357 に答える
0

リクエストR1が受信され、処理中R2R3R4がこの順序で受信された場合は、R2破棄R3され、処理が終了した後にR4処理される必要があります。 R

擬似コードは次のようなものです。

リクエストスレッドを受け取る

if current_request is null
    assign to current_request
else
    assign to next_request

プロセス リクエスト スレッド:

while true
    if current_request is not null
        process it
        set current_request = next_request, next_request = null

とへの変更は、同じ を使用して行う必要がありnext_requestます。current_requestlock

于 2012-10-31T20:27:01.470 に答える
0

これは、Reactive Extension で行うのが最適です。イベント トリガーの Throttle を使用するだけです。

于 2012-11-26T12:55:21.307 に答える