2

C# Win アプリケーションで 2 つのセカンダリ スレッドを実行しています。

最初のスレッドは、Sql Server プロファイル メッセージを読み取り、それを文字列としてリスト ボックスに追加して、一種のキューを形成します。他のスレッドは、これらのトレース メッセージを 1 つずつ送信し、それに応じてリストから削除します。

今、私はそれが問題を引き起こすと確信しています。1 つのスレッドのみが 2 つの関数のいずれかにアクセスできるようにする方法:

    void AddItemThreadSafe(string item)
    {
        this.Invoke((MethodInvoker)delegate
        {
            listBoxCollection.Items.Add(item);
        });
    }

    void RemoveItemThreadSafe()
    {
        this.Invoke((MethodInvoker)delegate
        {
            listBoxCollection.Items.RemoveAt(0);
        });
    }
4

3 に答える 3

5

一般に、lockコードのセクションへのスレッド アクセスを同期するには、を使用します。

private static object listLocker = new object();

void AddItemThreadSafe(string item)
{
    this.Invoke((MethodInvoker)delegate
    {
        lock (listLocker)
        {
            listBoxCollection.Items.Add(item);
        }
    });
}

void RemoveItemThreadSafe()
{
    this.Invoke((MethodInvoker)delegate
    {
        lock (listLocker)
        {
            listBoxCollection.Items.RemoveAt(0);
        }
    });
}

この特定のケース (私が間違っている場合は誰かが私を訂正してください) では、同じオブジェクトからメソッドを呼び出しているという事実により、アクセスが既に同期され、ロックが冗長になっていると思います。

于 2013-06-02T12:31:39.410 に答える
2

幸いなことに、フォームのInvokeメソッドは既に同期されています。Invokeメソッド/デリゲートをキューに入れ、フォームを作成した唯一の UI スレッドで実行されるようにするのがポイントです。

于 2013-06-02T13:37:53.890 に答える
1

ConcurrentBag クラス などの組み込みのスレッドセーフ コレクションを使用する

あなたの質問Isawから、ある種のキューが必要なので、ConcurrentQueue Classを使用してください

于 2013-06-02T12:46:30.517 に答える