我需要开发一个使用多线程的应用程序。
基本上,我有一个包含大约20万行的DataTable。 从每一行开始,我需要一个字段,将其与网页进行比较, 然后将其从数据表中删除。
问题是,服务于这些页面的服务器对并发请求有限制。 所以最多我可以同时要求3页。
我想通过使用线程池来实现这一点, 我甚至管理构建一个简单的应用程序(锁定数据表) 但我无法限制并发线程(即使使用SetMaxThreads),它似乎只是忽略了限制。
有没有人做过类似的东西? 我很乐意看到。
我尝试过使用信号量,但遇到了问题:
static SemaphoreSlim _sem = new SemaphoreSlim(3); // Capacity of 3
static List<string> records = new List<string>();
static void Main()
{
records.Add("aaa");
records.Add("bbb");
records.Add("ccc");
records.Add("ddd");
records.Add("eee");
records.Add("fff");
records.Add("ggg");
records.Add("iii");
records.Add("jjj");
for (int i = 0; i < records.Count; i++ )
{
new Thread(ThreadJob).Start(records[i]);
}
Console.WriteLine(records.Count);
Console.ReadLine();
}
static void ThreadJob(object id)
{
Console.WriteLine(id + " wants to enter");
_sem.Wait();
Console.WriteLine(id + " is in!"); // Only three threads
//Thread.Sleep(1000 * (int)id); // can be here at
Console.WriteLine(id + " is leaving"); // a time.
lock (records)
{
records.Remove((string)id);
}
_sem.Release();
}
这很好地运行,唯一的问题是,
Console.WriteLine(records.count);
返回不同的结果。 即使我知道它发生了,因为并非所有线程都已完成(我在删除所有记录之前调用records.count)我无法找到如何等待所有完成。
答案 0 :(得分:2)
答案 1 :(得分:1)
为什么不使用Parallel Extensions - 这会让事情变得更容易。
无论如何,你可能想要看的东西就像信号量。我在一两个月后写了一篇关于这个主题的博客文章,你可能觉得它很有用:https://colinmackay.scot/2011/03/30/using-semaphores-to-restrict-access-to-resources/
答案 2 :(得分:0)
答案 3 :(得分:0)
首先,应该 Console.WriteLine(id +“离开”); 在锁定之后和它发布信号量之前不会稍晚一点?
至于实际等待所有线程的完成,从长远来看,Groo的答案看起来更好,更强大,但作为这个特定代码的更快/更简单的解决方案,我想你也可以逃脱只是按顺序在你想要等待的所有线程上调用.Join()。
static List<Thread> ThreadList = new List<Thread>(); // To keep track of them
然后在启动线程时,将当前新的Thread行替换为:
ThreadList.Add(new Thread(ThreadJob).Start(records[i]));
然后就在Console.WriteLine之前:
foreach( Thread t in ThreadList )
{
t.Join();
}
如果任何线程没有终止,这将锁定,如果你想知道 - 哪些线程还没有完成,这个方法将不起作用。