Список вне диапазона

1

Я строю алгоритм SJF. У меня есть словарь, который я разделил на 2 списка. один список для имени и другой список для значений. Разумеется, словарь разделился после того, как я его отсортировал. Также у меня есть таймер.

Когда я запускаю код, который он разбил в Списке, и он говорит мне, что

Индекс был вне пределов досягаемости. Должен быть неотрицательным и меньше размера коллекции.

Я не знаю, как это происходит, потому что мой цикл - это точно размер словаря и размер списков.

Не могли бы вы посоветовать мне, как я могу исправить эту проблему?

   //Initializing the Dictionary  and the lists. 
    Dictionary<int, int> waytosave = new Dictionary<int, int>();

    List<int> saveName = new List<int>();
    List<int> saveValue = new List<int>();



   //Botton to run the algorithm 

        private void btnSFJ_Click(object sender, EventArgs e)
    {

        //the values inside the dictionary 
        waytosave.Add(0,100);
        waytosave.Add(1,10);
        waytosave.Add(2,30);
        waytosave.Add(3,500);
        waytosave.Add(4,5);
        waytosave.Add(5,13);
        waytosave.Add(6,200);
        waytosave.Add(7,89);
        waytosave.Add(8,248);
        waytosave.Add(9,136);
        waytosave.Add(10,458);
        waytosave.Add(11,743);

деление его на списки показалось мне лучшим способом получить значение и имя в одно и то же время.

        //Sort the dictionary by Value
        foreach(KeyValuePair<int, Int32> saveSFJ in waytosave.OrderBy(key => key.Value))
        {
            saveName.Add(saveSFJ.Key);
            saveValue.Add(saveSFJ.Value);
            txtOutput.Text += "\r\r\n" + "The name is:  " + saveSFJ.Key + "  the value is:  "+ saveSFJ.Value;

        }
        int numsaving = 12;
        int timesaving=0;


        for (int x = 0; x < numsaving; x++)
        {
            var timer = new System.Windows.Forms.Timer();
            int track = 1;
            timer.Tick += (timerObject, timerArgs) =>
            {
                timer.Interval = track * saveValue[x]*1000; //I am getting crashed at this point When ever my loop finished. 
                this.txtOutput.Text += "\r\r\n" + " the value is:   "
                                                + saveValue[x]
                                                + "The name is:     "
                                                + saveName[x];

                timesaving = timesaving + saveValue[x];
                ++track;
                if (track > numsaving)
                {
                    timer.Stop();
                    timer.Dispose();

                }
            };
            timer.Start();

        }
        this.txtOutput.Text += "\r\r\n" + "  Ends x " + timesaving.ToString();

    }
}

Я сбой, когда цикл завершает работу, и он просто запускается один раз

Теги:
timer
winforms

1 ответ

1
Лучший ответ

Ваша переменная x цикла фиксируется в закрытии.

Когда делегат позади timer.Tick работает, x не будет значением, которое было в момент создания функции, но текущее значение x (поскольку оно было захвачено). В это время x будет равно numsaving (из-за x++ в цикле for).

Чтобы решить эту проблему, вы можете скопировать значение x в другую локальную переменную, например:

int y = x;
timer.Tick += (timerObject, timerArgs) =>
{
    timer.Interval = track * saveValue[y]*1000; //I am getting crashed at this point When ever my loop finished. 
    this.txtOutput.Text += "\r\r\n" + " the value is:   "
                                    + saveValue[y]
                                    + "The name is:     "
                                    + saveName[y];

    timesaving = timesaving + saveValue[y];
    ++track;
    if (track > numsaving)
    {
            ...

Вы также можете использовать простой цикл foreach; и если вы используете Visual Studio 2012, вам не нужно создавать локальную копию переменной итерации:

foreach(var kvp in waytosave.OrderBy(key => key.Value))
{
    var timer = new System.Windows.Forms.Timer();
    int track = 1;
    timer.Tick += (timerObject, timerArgs) =>
    {
        timer.Interval = track * kvp.Value *1000;
        ...
  • 0
    Также см. Сообщение Эрика Липперта о закрытиях: blogs.msdn.com/b/ericlippert/archive/2009/11/12/…
  • 0
    Спасибо, это просто отлично работает. Я ценю ваше время и ваше предложение. это решает мою проблему. спасибо тебе большое
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню