我有一个WinForms C#应用程序(Web Crawler),它连接到WCF自托管服务,后者又连接到MS SQL数据库。
WebCrawler 启动(将用户登录等)LoginActual();
接收要处理的URL和
启动BackGroundWorker
实际启动抓取工具RunCrawler();
RunCrawler()从URL中获取要处理的HTML并获取html中的所有网址。该网址已添加到alOutUrls
,即ArrayList
。然后将URL发送到SendURls
();如果正在处理的URL返回错误,例如404,则SendError
();被称为。
如果alOutUrls
中包含的网址超过100个网址,则会将网址添加到队列中以便在任务中进行处理。并启动RunQueue
方法作为新任务。
其他
它在foreach中通过alOutUrls进行迭代,向Raptor Service API(RAPI)发送URL和附加信息。
RunQueue()在Queue
语句中迭代While
,向Raptor服务API(RAPI)发送从队列中获取的URL和其他附加信息。
但是,始终会出现以下问题!
RunQueue
()方法似乎不在后台运行,但会阻止应用程序直到完成;这就解决了这个问题。巨大的更新 代码的大规模简化就在这里 - 它仍然存在同样的问题。
private ArrayList alOutUrls = new ArrayList();
private void RunCrawler()
{
while(true)
{
int ErrorCode = 0;
string cu = alUrls[0].ToString();
string html = LoadUrlIfNotContentType(cu, out ErrorCode);
if (!string.IsNullOrEmpty(html))
{
alOutUrls = GetUrls(html, cu);
SendUrls(cu, ErrorCode); // Send the URLS
}
else
SendError(cu, ErrorCode); // Send the StatusCode of the Url 404, 500 etc
alUrls.RemoveAt(0);
alUrls.AddRange(RAPI.SendUrls());
}
}
private Task tRunQueue = null;
private Queue<string> bigqueue = new Queue<string>();
private bool IsContentObject = false;
private void SendUrls(string cu, int ErrorCode)
{
foreach (string u in alOutUrls)
{
bigqueue.Enqueue(u);
}
if(tRunQueue == null)
{
tRunQueue = new Task(() => RunQueue(cu, IsContentObject, ErrorCode));
tRunQueue.Start();
}
}
private void RunQueue(string cu, bool IsContentObject, int ErrorCode)
{
while (bgwCrawler.CancellationPending != true)
{
if (bigqueue.Count > 0)
{
string url = bigqueue.Dequeue();
string urlHash = Hashing.HashString(url.ToLowerInvariant().Trim().ToString());
RAPI.ReceiveUrls(url, urlHash, cu, IsContentObject, ErrorCode);
}
}
}
所以重申问题是:
任何见解都会有所帮助,这是一个非常重要的计划 旨在保护儿童免遭性剥削和谋杀。
答案 0 :(得分:1)
发现问题:
Application.DoEvents();
RunQueue应该在后台运行。但是通过调用Application.DoEvents(),您正在劫持UI处理。我不知道从后台线程调用它的确切效果,但它不是很好。