2013-04-06 2 views
0

Я хочу прокрутить список URL-адресов и проверить каждый URL-адрес, если веб-сайт не работает или не использует несколько потоков.Прокрутите список и создайте многопоточные потоки

Мой подход:

  while (_lURLs.Count > 0) 
      { 
       while (_iRunningThreads < _iNumThreads) 
       { 
        Thread t = new Thread(new ParameterizedThreadStart(CheckWebsite));       
        string strUrl = GetNextURL(); 
        if (!string.IsNullOrEmpty(strUrl)) 
        { 
         t.Start(strUrl); 
         _iRunningThreads++; 
        } 
        else 
        { 
         break; 
        } 
       } 
      } 

    private string GetNextURL() 
    { 
     lock (_lURLs) 
     { 
      if (_lURLs.Count > 0) 
      { 
       string strRetVal = _lURLs[0]; 
       _lURLs.RemoveAt(0); 
       return strRetVal; 
      } 
      else 
      { 
       return string.Empty; 
      } 
     } 
    } 

Когда поток закончил _iRunningThreads свойство получает убавления.

Моя проблема: внешняя петля блокирует все «while (_lURLs.Count > 0)». Добавление Application.DoEvents() во внешний цикл while помогает, но я хочу использовать код в библиотеке C#, где Application.DoEvents() недоступен.

Благодарим за помощь.

+0

Эта операция снаружи, блокирующий op. Просто запустите его на Thread (Backgroundworker) из основной программы. –

+3

Каков ваш метод CheckWebsite на самом деле? Кажется, что асинхронные методы были бы более подходящими, чем потоки для этого типа задач. –

+1

см. Http://stackoverflow.com/questions/15850633/c-sharp-threading-issue-best-practises – Filip

ответ

1

Я думаю, что использование .NET ThreadPool было бы хорошей идеей в этом случае, если задачи занимают довольно короткое время.

Отъезд: http://msdn.microsoft.com/en-us/library/4yd16hza.aspx

Это позволяет упростить код немного как ThreadPool автоматически управляет счетчик рабочих потоков. Вам просто нужно позвонить ThreadPool.QueueUserWorkItem за каждый URL, который у вас есть, и увеличить счетчик выполняемых задач. Очередь пунктов в ThreadPool не будет блокировать поток пользовательского интерфейса.

Задачи ThreadPool уменьшают счетчик (как у вас есть), и когда счетчик достигает нуля (все задачи были запущены) вызывают функцию обратного вызова, чтобы ваш основной код знал, когда все URL-адреса были обработаны. Вы можете обновить пользовательский интерфейс или что-нибудь еще, что вы хотите сделать из этого обратного вызова.

3

Вместо того чтобы управлять нитями самостоятельно, вы можете использовать TPL.
Кроме того, если вы используете .Net Framework 4.5 вы можете даже добавить асинхр/ждать и WhenAll метод для предотвращения блокировки ...

Вот небольшой пример:

private async Task CheckUrl() 
    { 
     List<Task> tasks = new List<Task>(); 

     string url = GetNextUrl(); 
     while (!String.IsNullOrEmpty(url)) 
     { 
      tasks.Add(Task.Run(() => CheckWebSite(url))); 
      url = GetNextUrl(); 
     } 

     await Task.WhenAll(tasks); 

     // All tasks have finished... 

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