我有一段代码可以打开一个数据阅读器,每条记录(包含一个网址)下载&处理该页面。
使多线程成为最简单的方法是什么,比方说,有10个插槽可用于同时下载和处理页面,并且当插槽可用时,下一行正在读取等等。
我无法使用WebClient.DownloadDataAsync
这是我试图做的,但它没有奏效(即“工人”从未运行过):
using (IDataReader dr = q.ExecuteReader())
{
ThreadPool.SetMaxThreads(10, 10);
int workerThreads = 0;
int completionPortThreads = 0;
while (dr.Read())
{
do
{
ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
if (workerThreads == 0)
{
Thread.Sleep(100);
}
} while (workerThreads == 0);
Database.Log l = new Database.Log();
l.Load(dr);
ThreadPool.QueueUserWorkItem(delegate(object threadContext)
{
Database.Log log = threadContext as Database.Log;
Scraper scraper = new Scraper();
dc.Product p = scraper.GetProduct(log, log.Url, true);
ManualResetEvent done = new ManualResetEvent(false);
done.Set();
}, l);
}
}
答案 0 :(得分:1)
您通常不需要使用Max线程(我相信它默认为每个proc为工作者25个,IO为IO)。您可以考虑设置Min线程,以确保始终有一个好的数字。
您也不需要调用GetAvailableThreads。您可以开始调用QueueUserWorkItem并让它完成所有工作。你可以通过简单地调用QueueUserWorkItem来重现你的问题吗?
您还可以查看Parallel Task Library,其中包含帮助方法,可以使这类内容更易于管理和管理。