Pass each list item to a new thread one by one [duplicate]

两盒软妹~` 提交于 2019-12-04 03:40:15

问题


What I'm trying to do is very simple,
I scan a list of strings, then, I pass each string to a new thread for printing.

using System;
using System.Collections.Generic;
using System.Threading;

namespace MultithreadingSynchronization
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> stringList = new List<string> { "server1", "server2", "server3", "server4", "server5", "server6", "server7", "server8", "server9"};

            foreach (string server in stringList)
            {
                ThreadStart work = delegate { Threadjob(server); };
                new Thread(work).Start();
                //Thread.Sleep(10); // 10 ms delay of main thread
            }
        }

        public static void Threadjob(object server)
        {
            Console.WriteLine(server);
        }
    }
}

From some reason, there are threads that received wrong value, therefore, the output presents some duplicated strings, and also miss some strings.
I'm expecting for this output (the order isn't important):

server1
server2
server3
server4
server5
server6
server7
server8
server9

But, sometimes I get this:

server3
server2
server5
server5
server7
server4
server8
server9
server9

and sometimes I get this:

server2
server2
server4
server3
server6
server7
server7
server8
server9

etc.

indeed, if I put a delay after each thread creating, I get what I expect to get.

Any idea?


回答1:


You should make local copy of variable. Try this:

    foreach (string server in stringList)
    {
        string local = server;
        ThreadStart work = delegate { Threadjob(local); };
        new Thread(work).Start();
        //Thread.Sleep(10); // 10 ms delay of main thread
    }

More info here: Captured variable in a loop in C#




回答2:


new Thread(Threadjob).Start(server);

Done! However, it may be more advisable to use tasks rather than threads - or at least ThreadPool.




回答3:


OK, I think I get it.
Froeach loop hold a pointer, and changes it on each iteration. Sometimes, the thread is created, but still not running. meanwhile, the loop changes the pointer at the following iteration, and when the thread starts its job, it get the current pointer's value (the subsequent string).

BTW, I found another solution here, how to pass parameters to main function of the thread, so I fixed my loop and it works properly now

foreach (string server in stringList)
{
    Thread thread1 = new Thread(new ParameterizedThreadStart(Threadjob));
    thread1.Start(server); 
}


来源:https://stackoverflow.com/questions/20503837/pass-each-list-item-to-a-new-thread-one-by-one

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!