Task.Start()在完成之前不会返回(大更新)

时间:2015-05-21 21:32:57

标签: c# winforms wcf task backgroundworker

我有一个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和其他附加信息。

但是,始终会出现以下问题!

  1. 从客户端发送到服务主机的超时时间
  2. RunQueue()方法似乎不在后台运行,但会阻止应用程序直到完成;这就解决了这个问题。
  3. 巨大的更新 代码的大规模简化就在这里 - 它仍然存在同样的问题。

     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);
                    }                
                }
            }
    

    所以重申问题是:

    1. 从客户端发送到服务主机的时间超时。
    2. RunQueue()方法不在后台运行。
    3.   

      任何见解都会有所帮助,这是一个非常重要的计划   旨在保护儿童免遭性剥削和谋杀。

1 个答案:

答案 0 :(得分:1)

发现问题:

Application.DoEvents();

RunQueue应该在后台运行。但是通过调用Application.DoEvents(),您正在劫持UI处理。我不知道从后台线程调用它的确切效果,但它不是很好。