3

現在、データ量に基づいて関数の X タスクを作成する関数があり、各スレッドが実行したデータの数で int 変数を更新して、progressBar を表示したいと考えています。

現在、すべての UI はタイマーから更新されるため、スレッドから委譲して UI を更新する代わりに (この場合、これはさらに面倒なことになると思います)、後でタイマーによって選択されるカウントで変数を更新します。 UIを更新します。

私が知りたいのは、ロックは変数を更新する良い方法でしょうか、それとももっと良い方法がありますか?

非常に頻繁に使用されている場合、タイマーはその変数を読み取ることができますか、それとも更新中に古い値であっても読み取ることができますか?

大まかな例を次に示します。

private static readonly object counterLock = new object();
int myCounter = 0;

private void FunctionExecutedByAllRunnningThreads()
{
    int executed = 0;
    foreach (some data)
    {
        //do something with this data
        executed++;
    }
    lock (counterLock)
        myCounter += executed;
}
4

3 に答える 3

8

私が知りたいのは、ロックは変数を更新する良い方法でしょうか、それとももっと良い方法がありますか?

値をインクリメントするだけの場合は、Interlocked.Incrementを使用して、. なしで安全にインクリメントできますlock

これをバッチ処理する場合は、Interlocked.Addを使用すると、スレッド ローカルの合計値を一度にカウンターに追加できます。この場合もロックは必要ありません。

于 2012-06-21T15:08:22.720 に答える
2

これに使用Interlocked.Add()します。Interlocked.Increment()(カウンターに1以上加算しているように見えるので使用できません)

于 2012-06-21T15:08:54.243 に答える
1

.NET には、これを安全に行う方法が含まれています。Interlocked.Increment

を使用することもできInterlocked.Addます。他にも役立つ方法がたくさんあります。Interlocked

int myCounter = 0;

private void FunctionExecutedByAllRunnningThreads()
{
    int executed = 0;
    foreach (some data)
    {
        //do something with this data
        executed++;
    }
    Interlocked.Add(ref myCounter, executed);
}
于 2012-06-21T15:08:54.893 に答える