1

I am trying to use multithreading to call this function. When I run the program I get an exception "Index out of range". When I try to print the values of 'i' I get serviceids list.count each times.

In my case the loop should go from 0 to 1 and print The value of i this time is 0 The value of i this time is 1

but it prints both times

The value of i this time is 2 The value of i this time is 2

What is wrong with my code and how can I fix it ? DataDownloader downloader = new DataDownloader();

    for (int i = 0; i < serviceidslist.Count; i++)
    {
        BackgroundWorker bw = new BackgroundWorker();

        bw.DoWork += new DoWorkEventHandler(
        delegate(object o, DoWorkEventArgs argss)
        {
            BackgroundWorker b = o as BackgroundWorker;

            Console.WriteLine("The value of i this time is {0}", i);
            downloader.DoDownload(serviceidslist[i]);



        });

        bw.RunWorkerAsync();
    }
zzzzz
  • 1,209
  • 2
  • 18
  • 45

2 Answers2

4

Just an idea, but add a local variable and assign it to i:

int temp = i;

Then use it:

Console.WriteLine("The value of i this time is {0}", temp);
downloader.DoDownload(serviceidslist[temp]);

I think the issue could be that your BackgroundWorker is closing over the variable and not the value hence the need to store a copy of it each time in your loop.

also see here

What are 'closures' in C#? [duplicate]

Community
  • 1
  • 1
Ric
  • 12,855
  • 3
  • 30
  • 36
3

The issue is with the usage of the variable i.

Try with this:

for (int i = 0; i < serviceidslist.Count; i++)
{
    var index = i;
    BackgroundWorker bw = new BackgroundWorker();

    bw.DoWork += new DoWorkEventHandler(
    delegate(object o, DoWorkEventArgs argss)
    {
        BackgroundWorker b = o as BackgroundWorker;

        Console.WriteLine("The value of i this time is {0}", index );
        downloader.DoDownload(serviceidslist[index ]);



    });

    bw.RunWorkerAsync();
}`
mhttk
  • 1,688
  • 1
  • 16
  • 29