我写了一个可以处理多线程的程序。
该程序将启动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”):
完整代码:
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();
}
}
}