代码似乎在 Parallel.For 循环完成之前继续进行

Code seems to move on prior to Parallel.For loops finishing

我正在努力使用 Parallel.For 循环。我可以看出他们确实加快了我的长 运行 代码的速度,但我得到了空对象错误,就好像代码在完成并行循环之前继续前进一样。下面是我的代码,注释掉了我试过的 Parallel.For 语句。

public bool Calculate()
{
    // make list of all possible flops 22100
    List<Flop> flops = new List<Flop>();
    CardSet deck = new CardSet();
    for (int i = 0; i < deck.Size() - 2; i++)
    {
        SbCard card1 = deck.GetCard(i);
        for (int j = i + 1; j < deck.Size() - 1; j++)
        {
            SbCard card2 = deck.GetCard(j);
            for (int k = j + 1; k < deck.Size(); k++)
            {
                SbCard card3 = deck.GetCard(k);
                flops.Add(new Flop(card1, card2, card3));
            }
        }
    }

    int progress = 0;
    var watch = System.Diagnostics.Stopwatch.StartNew();

    // Loop over each flop
    //Parallel.For(0, flops.Count, i =>
    for (int i = 0; i < flops.Count; i++)
    {
        Dictionary<FlopEquityHoldemHandPair, FlopEquityHoldemHandPair> flopPairs =
        new Dictionary<FlopEquityHoldemHandPair, FlopEquityHoldemHandPair>();
        Flop flop = flops[i];
        String filePath = Directory.GetCurrentDirectory() + "\flops\" +
        flop.GetSorted() + ".txt";

        if (!File.Exists(filePath))
        {
            // make list of all available starting hands
            List<HoldemHand> hands = new List<HoldemHand>();
            deck = new CardSet();
            deck.RemoveAll(flop);
            for (int j = 0; j < deck.Size() - 1; j++)
            {
                SbCard card1 = deck.GetCard(j);
                for (int k = j + 1; k < deck.Size(); k++)
                {
                    SbCard card2 = deck.GetCard(k);
                    hands.Add(new HoldemHand(card1, card2));
                }
            }

            // loop over all hand vs hand combos
            //Parallel.For(0, hands.Count - 1, j =>
            for (int j = 0; j < hands.Count - 1; j++)
            {
                HoldemHand hand1 = hands[j];
                //Parallel.For(j + 1, hands.Count, k =>
                for (int k = j + 1; k < hands.Count; k++)
                {
                    HoldemHand hand2 = hands[k];
                    if (!hand1.Contains(hand2))
                    {
                        FlopEquityHoldemHandPair holdemHandPair = new
                          FlopEquityHoldemHandPair(hand1, hand2);
                        if (!flopPairs.ContainsKey(holdemHandPair))
                        {
                            // next line triggers a loop of 1980 iterations
                            flopPairs.Add(holdemHandPair, new
                            FlopEquityHoldemHandPair(new
                            EquityHoldemHand(hand1), new
                            EquityHoldemHand(hand2), flop));
                        }
                    }
                }//);
            }//);


            // WRITE FILE FOR CURRENT FLOP
            StringBuilder sb = new StringBuilder();
            foreach (FlopEquityHoldemHandPair pair in flopPairs.Values)
            {
                // Null value appears in flopPairs.Values and the list of values is around 200 short of the 600k values it should have
                sb.AppendLine(pair.ToString());
            }
            File.WriteAllText(filePath, sb.ToString());

            // reports calculation progress 1% at a time
            int num = ((int)(i * 100 / 22100));
            if (num > progress)
            {
                progress = num;
                Console.WriteLine("Progress: " + progress + "%");
            }
        }
    }//);

    watch.Stop();
    var elapsedMs = watch.ElapsedMilliseconds;

    Console.WriteLine("Finished in " + elapsedMs / 60000 + "mins");
    return true;
}

当我到达此代码后期的 foreach 循环时,flopPairs 中的一些项目。值为 null 并且字典没有应有的那么大 - 好像在代码继续之前某些计算没有完成。很抱歉,如果没有更多代码,这段代码将无法运行,但可以提供很多。如果问题对某些人来说不是很明显,我可以尝试提供一个最小的简化示例。

正如 John Wu 在评论中所说,Dictionary 不是线程安全的,这导致了我的问题。使用 ConcurrentDictionary 是正确答案