2015-05-21 2 views
-1

У меня есть приложение WinForms C# (Web Crawler), которое подключается к самостоящей службе WCF, которая, в свою очередь, подключается к базе данных MS SQL.Task.Start() не возвращается до завершения (Big Update)

В WebCrawler Запускает (регистрирует пользователя в и т.д.) LoginActual(); Получает URL для обработки и запускает BackGroundWorker, который фактически запускает Crawler RunCrawler();

RunCrawler() получает HTML из URL в процесс и получает все URL-адреса в html. URL-адреса добавляются к alOutUrls, который является ArrayList. Затем URL-адреса отправляются на SendURls(); Если обработанный URL возвратил ошибку, например 404, то SendError(); называется.

Если alOutUrls имеет более 100 URL-адресов, то он добавляет URL-адреса в очередь для обработки в Задаче. И запускает метод RunQueue в качестве новой задачи. Else Итерирует через alOutUrls в foreach, отправляя API Raptor Service API (RAPI) URL и дополнительную информацию.

RunQueue() итерации через Queue в While заявления посылающего API Raptor Service (RAPI) URL-адрес, взятый из очереди и другой дополнительной информации.

Тем не менее, следующие проблемы: все время!

  1. Время Ушли на Посылать от клиента к хосту службы
  2. Метод RunQueue(), кажется, не работает в фоновом режиме, но блокирует приложение, пока не будет завершено; который побеждает проблему.

ОГРОМНЫЙ UPDATE Массивный упрощение кода здесь - который по-прежнему имеет те же проблемы.

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() не работает в фоновом режиме.

Любые идеи было бы полезно, это очень важная программа предназначена для защиты детей от сексуальной эксплуатации и убийства.

+4

Это слишком много кода. Пожалуйста, создайте [** Минимальный **, Полный и Подтверждаемый пример] (http://stackoverflow.com/help/mcve). 19 последовательных строк кода с комментариями не должны быть в столбце переполнения стека. –

+0

Изменение кода может изменить проблему. –

+7

Не меняя код, он не может дать никаких ответов. – Stefan

ответ

1

Нашли проблему:

Application.DoEvents(); 

RunQueue должен быть запущен в фоновом режиме. Но, вызывая Application.DoEvents(), вы захватываете обработку пользовательского интерфейса. Я не знаю точного эффекта вызова из фонового потока, но это не может быть хорошо.

+0

Это может быть ОДНА проблема. Но я не уверен, что это единственный. – Kryptos

+0

Я тоже, но вы должны где-то начинать. –

Смежные вопросы