6

これは私だけが書いて使っている小さなプログラムです。

ここで、この問題の原因となったハッシュセットを使用するすべての領域のコードを記述します

これがどのように可能かわかりません。この項目は MainWindow でのみ使用されています

hsProxyList はハッシュセットです

  HashSet<string> hsProxyList = new HashSet<string>();

エラーは以下の繰り返しで発生しました

 lock (hsProxyList)
            {
    int irRandomProxyNumber = GenerateRandomValue.GenerateRandomValueMin(hsProxyList.Count, 0);
    int irLocalCounter = 0;
    foreach (var vrProxy in hsProxyList)
    {
       if (irLocalCounter == irRandomProxyNumber)
       {
       srSelectedProxy = vrProxy;
       break;
       }
         irLocalCounter++;
       }
    }
}

hsProxyList を使用するその他の場所

カウントを取得しているときにオブジェクトをロックしません-これはエラーを引き起こさないと思いますが、正しくない可能性があります-致命的に重要ではありません

 lblProxyCount.Content = "remaining proxy count: " + hsProxyList.Count;

新着

lock (hsProxyList)
{
    hsProxyList.Remove(srSelectedProxy);
}

新着

lock (hsProxyList)
{
    hsProxyList = new HashSet<string>();
    foreach (var vrLine in File.ReadLines(cmbBoxSelectProxy.SelectedItem.ToString()))
    {
        hsProxyList.Add(vrLine);
    }
}

ご覧のとおり、どこでもロックを使用しています。これはマルチスレッドソフトウェアです。すべての hsProxyList は MainWindow.xaml.cs で使用されています - これは C# WPF アプリケーションです

4

2 に答える 2

9

問題はあなたがどこにいるのかです

lock (hsProxyList)
{
    hsProxyList = new HashSet<string>();
    // etc
}

すべてのロックは特定のオブジェクトに適用されますが、オブジェクトを変更するhsProxyList = new HashSet<string>();と、変数 hsProxyList が参照するオブジェクトはロックされなくなります。

于 2013-05-26T14:05:36.857 に答える
3

ここには 2 つの問題があります。1つ目は、すでに指摘されているように、オブジェクトのhsProxyListポイントを次のように変更しながら、ハッシュセットをロックしていることです。

lock (hsProxyList)
{
    hsProxyList = new HashSet<string>();
    // hsProxyList is no longer locked.
}

Count2 番目の (そしてより微妙な) 問題は、ロックを必要としないと想定していることです。これは安全な仮定ではありません。HashSetまず、どのように実装されているかわかりません。Countが操作であるという事実O(1)は、カウントを追跡するメンバー変数があることを示しています。これは、 onAddまたはRemovethis 変数を更新する必要があることを意味します。の実装は次のAddようになります。

bool Add( T item ) {
    this.count++;
    // Point A.
    addItemToHashSet(item);
}

count変数がインクリメントされからアイテムが追加されることに注意してください。スレッドの呼び出しAddポイント Aで中断され、呼び出した他のスレッドCountが実行された場合、実際の要素の数よりも多いカウントを受け取ります (countはインクリメントされていますが、インクリメントされaddItemToHashSetていません)。

これは重大な結果をもたらさないかもしれませんが、Count要素を繰り返し処理している場合、クラッシュを引き起こす可能性があります。を呼び出す場合も、同様の動作が発生する可能性がありRemoveます。

于 2013-05-26T14:45:54.720 に答える