2015-09-03 1 views
1

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

Для каждого URL, я огонь запрашивайте HTTP таким образом:

HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; 
HttpWebResponse response = request.GetResponse() as HttpWebResponse; 

Проблема: Довольно часто сервер URL отсутствует, что означает request.GetResponse() будет висеть на request.Timeout миллисекунд. Мне нужна система , чтобы не стоять в ожидании таймаута; вместо этого я хочу использовать свободное время для запуска остальных запросов, пока какой-то запрос ожидает ответа.

мое решение я хотя о диспетчерских каждого запроса в другой задаче Мое решение, таким образом, выглядит следующим образом:

Task[] tasks = new Task[numberOfUrls]; 
for (int i = 0; i < numberOfUrls; ++i) 
{ 
    int index = i; 
    tasks[index] = Task.Factory.StartNew(() => Request(urls[index])); 
} 

Task.WaitAll(tasks); 

Вопрос: что такое правильный способ сделать решить эту проблему?

Я не уверен, что мой путь - это правильный способ, потому что после прочтения большого количества материала обо всем C# асинхронном/многопоточном/параллельном механизме (с которым я не очень хорошо знаком) я действительно запутался. На этом этапе я не уверен, что делаю это асинхронно или с несколькими потоками или что-то еще. Я прочитал предложения о том, что я должен сделать метод, который запускает запросы async, и их назовут его и ждут. Но потом я также обнаружил, что люди говорят, что не будут использовать параллелизм и так далее.

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

ответ

0

Здесь важно, чтобы вам нужно было одновременно отправлять определенное количество HTTP-запросов. Всегда есть много выдающихся. Это то, что вы получаете здесь.

Технология, которую вы используете для совершения этого, не имеет значения.

Что я буду делать, это использовать async IO для HTTP-запросов и использовать one of the common techniques of processing a list of items in parallel asynchronously.

Вы, вероятно, должны использовать современный класс HttpClient, который прекрасно работает с ожиданием. Но это не обязательно.

Определить степень параллелизма экспериментально.


public static Task ForEachAsync<T>(this IEnumerable<T> source, int dop, Func<T, Task> body) 
{ 
    return Task.WhenAll( 
     from partition in Partitioner.Create(source).GetPartitions(dop) 
     select Task.Run(async delegate { 
      using (partition) 
       while (partition.MoveNext()) 
        await body(partition.Current); 
     })); 
} 
Смежные вопросы