具有多线程的ThreadPool.QueueUserWorkItem对所有线程仅使用一个参数

时间:2018-12-01 10:57:46

标签: c# multithreading threadpool

我写了一个可以处理多线程的程序。
该程序将启动4个线程,创建一个包含400个链接的队列,每个线程将从队列中获取链接,并向该链接发送GET请求。

我使用ThreadPool创建了4个线程:

for (int i = 0; i < 4; i++)
{
    ThreadPool.QueueUserWorkItem(state => worker(i));
}

worker()函数应打印我作为参数提供的工作程序ID:

Console.WriteLine("Worker {0} is processing item {1} with result {2}", workerId, workItem, res);  

我希望它打印出类似“工人1 ....,工人2 ...,工人3 ...,工人4 ...,工人1 ...”的字样。
但是,当我运行该程序时,它会打印相同的ID 4(“ Worker 4”):
enter image description here

完整代码:

using System;
using System.Collections.Concurrent;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;

namespace PalyGround
{
    class Program
    {
        static void Main(string[] args)
        {
            var watch = System.Diagnostics.Stopwatch.StartNew();
            RunThreadPool();
            watch.Stop();
            var elapsedMs = watch.ElapsedMilliseconds;
            Console.WriteLine("[*] Elapsed time: {0}", elapsedMs / 1000);
            Console.ReadLine();
        }

        static BlockingCollection<string> inputQueue = new BlockingCollection<string>();

        // https://stackoverflow.com/questions/6529659/wait-for-queueuserworkitem-to-complete
        private static ManualResetEvent resetEvent = new ManualResetEvent(false);

        private static void RunThreadPool()
        {
            string url = @"https://google.com";
            for (int i = 0; i < 4; i++)
            {
                ThreadPool.QueueUserWorkItem(state => worker(i));
            }

            for (int i = 0; i < 400; ++i)
            {
                //Console.WriteLine("Queueing work item {0}", url + "/" + i);
                inputQueue.Add(url + "/" + i);
                //Thread.Sleep(50);
            }

            Console.WriteLine("Stopping adding.");
            inputQueue.CompleteAdding();

            resetEvent.WaitOne();
            Console.WriteLine("Done.");
        }

        // https://stackoverflow.com/a/22689821/2153777
        static void worker(int workerId)
        {
            Console.WriteLine("Worker {0} is starting.", workerId);

            foreach (var workItem in inputQueue.GetConsumingEnumerable())
            {
                string res = "";
                //Console.WriteLine("Worker {0} is processing item {1}", workerId, workItem);
                try
                {
                    res = Get(workItem);
                }
                catch (Exception)
                {
                    res = "404";
                }
                Console.WriteLine("Worker {0} is processing item {1} with result {2}", workerId, workItem, res);
                //Thread.Sleep(100);          // Simulate work.
            }
            resetEvent.Set();
            Console.WriteLine("Worker {0} is stopping.", workerId);
        }

        // https://stackoverflow.com/a/27108442/2153777
        public static string Get(string uri)
        {
            HttpStatusCode status;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                status = response.StatusCode;
            }

            //Thread.Sleep(2000);
            return status.ToString() + "; Thread: " + Thread.CurrentThread.ManagedThreadId.ToString();
        }
    }
}

0 个答案:

没有答案