简体   繁体   中英

“Collection was modified; enumeration operation may not execute” when running the same background worker on 2+ instances of a form simultaneously

I have ac# windows form where the user enters a set of parameters, and those parameters are then analyzed against a set of data to return a result. This analysis takes place on a background worker, by initializing a Backtest object and iterating over a string list symbolParams built from the values passed in through the form. When running the worker on one form, it works properly.

However, if I open up a second form, put in a new set of parameters, and run the worker on that form while the worker on the first form is still running, I get a "Collection was modified" error on the string list.

Seems as though the two background workers are affecting each other's symbolParams list somehow. What's happening? How can this be fixed to allow multiple instances of this form to run this background worker simultaneously?

OptimizerForm.cs

public partial class OptimizerForm : Form
{

    public static List<List<String>> backtestSymbolParams = new List<List<String>> { };

    private void button15_Click(object sender, EventArgs e)
    { 
        //Get parameters from the form
        //Make a list for every param
        string[] startEndTimes = textBox3.Text.Split(',');
        string[] incrementPrices = textBox4.Text.Split(',');
        string[] incrementSizes = textBox5.Text.Split(',');
        string[] autoBalances = textBox6.Text.Split(',');
        string[] hardStops = textBox7.Text.Split(',');

        //Add every combo to symbol test params
        for (int a = 0; a < startEndTimes.Length; a++)
        {
            for (int b = 0; b < incrementPrices.Length; b++)
            {
                for (int c = 0; c < incrementSizes.Length; c++)
                {
                    for (int d = 0; d < autoBalances.Length; d++)
                    {
                        for (int f = 0; f < hardStops.Length; f++)
                        {
                            backtestSymbolParams.Add( new List<string> { symbol, startEndTimes[a].Split('-')[0], startEndTimes[a].Split('-')[1], incrementPrices[b],
                                incrementSizes[c], autoBalances[d], hardStops[f] });
                        }
                    }
                }
            }
        }

        backgroundWorker1.RunWorkerAsync();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        //Initialize Backtest instance with parameters gathered from the form 
        Backtest backtest = new Backtest(backtestSymbolParams, backtestSymbolDates, sender as BackgroundWorker);

        TestResult testResult = new TestResult();

        //Run the analysis
        testResult = backtest.Run();

        e.Result = testResult;
    }
}

Backtest.cs

//Backtest Constructor
public Backtest(List<List<string>> _symbolParams, Dictionary<string,       List<string>> _symbolDates, BackgroundWorker _bw)
{
    symbolParams = _symbolParams;
    symbolDates = _symbolDates;
    bw = _bw;
}

//Backtest.Run()
public TestResult Run()
{
    int symbolCount = 1;

    //Collection modified exception occurs here
    foreach (List<string> symbolParam in symbolParams) {
       //do stuff
    }
}

It seems like your symbolParams variable in Backtest class is static , so simply mark it as private field for your class.

Also you have some issues with naming standards - method parameters should not start with _ , though fields should, so your constructor should looks like:

private List<List<String>> _symbolParams = new List<List<String>> { };

//Backtest Constructor
public Backtest(List<List<string>> symbolParams,
                Dictionary<string, List<string>> symbolDates,
                BackgroundWorker bw)
{
    _symbolParams = symbolParams;
    _symbolDates = symbolDates;
    _bw = bw;
}

And, as far as I can see, you're using BackgroundWorker as Task so probably you should use TPL itself, without old legacy classes

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM