2015-08-08 2 views
2

Я пытаюсь измерить улучшение количества времени, если я использую Http Async вместо Sync one, но код ниже взаимоблокировок из-за контекстов метода Async, которые я искал и нашел, можно использовать ConfigureAwait (false), чтобы исправить ситуацию, но код все еще блокируется. Любые предложения о том, как я могу это исправить?Асинхронный код блокировки даже после использования ConfigureAwait (false)

class Program 
{ 
    static void Main(string[] args) 
    { 
     Stopwatch stopwatch = new Stopwatch(); 
     var entities = new List<string>() { "iron+man+3", "dark+knight+rises", "frozen+movie" }; 
     stopwatch.Start(); 
     int taskStatus = AsyncGet(entities).Result; 
     stopwatch.Stop(); 
     Console.WriteLine(stopwatch.ElapsedTicks); 
     stopwatch.Reset(); 
     stopwatch.Start(); 
     SyncGet(entities); 
     stopwatch.Stop(); 
     Console.WriteLine(stopwatch.ElapsedTicks); 
     var depTime = DateTime.UtcNow; 
     depTime = depTime.AddMilliseconds(-depTime.Millisecond); 
     Console.WriteLine(depTime.ToString("yyyy-MM-ddTHH:mm:ss.fff")); 
     Console.Read(); 
    } 

    private static async Task<int> AsyncGet(List<string> entities) 
    { 
     var taskHttpList = new List<Task<WebResponse>>(); 
     var taskStreamList = new List<Task<string>>(); 
     var uriTemplate = "https://www.google.co.in/?#q={0}"; 
     foreach (var entity in entities) 
     { 
      Uri uri = new Uri(string.Format(uriTemplate, entity)); 
      var request = WebRequest.Create(uri); 
      taskHttpList.Add(request.GetResponseAsync()); 
     } 
     foreach (var task1 in taskHttpList) 
     { 
      var response = (HttpWebResponse)await task1.ConfigureAwait(false); 
      taskStreamList.Add((new StreamReader(response.GetResponseStream())).ReadToEndAsync()); 
     } 
     foreach (var task in taskStreamList) 
     { 
      var responseStr = (String)await task.ConfigureAwait(false); 
     } 
     return 0; 
    } 

    private static void SyncGet(List<string> entities) 
    { 
     var uriTemplate = "https://www.google.co.in/?#q={0}"; 
     foreach (var entity in entities) 
     { 
      Uri uri = new Uri(string.Format(uriTemplate, entity)); 
      var request = WebRequest.Create(uri); 
      var response = request.GetResponse(); 
      var str = new StreamReader(response.GetResponseStream()).ReadToEnd(); 
     } 
    } 
} 
+0

Вы пытались реализовать AsyncGet, подобный SyncGet, то есть один цикл foreach с двумя «ожиданиями» внутри? – alexm

+0

Да, и это работает, но тогда вся идея асинхронизации HTTP теряется. Я просто пытаюсь понять, если начать кучу HTTP-асинхронного запроса, а затем ждать их после того, как все запросы начались, я получаю любое улучшение производительности с точки зрения времени. – user1017860

+2

Вы ничего не распоряжаетесь. Это может привести к тому, что пул соединений станет исчерпан, что приведет к блокировке. Утилизируйте все ресурсы. – usr

ответ

2

Я предполагаю, что существует ограничение на количество потоков, выполняющих события завершения ввода-вывода. Вместо обработки его в Lockstep моды построить полную цепочку заданий на работы пункта:

private static async Task<int> AsyncGet(List<string> entities) 
{ 
    var tasks = new List<Task<string>>(); 

     foreach (var entity in entities) 
     { 
     var t = AsyncGetResponse(entity); 
     tasks.Add(t); 
     } 

     await Task.WaitAll(tasks.ToArray()).ConfigureAwait(false); 
     return 0 
    } 

static async Task<string> AsyncGetResponse(string entity) 
{ 
     const string uriTemplate = "https://www.google.co.in/?#q={0}"; 
     Uri uri = new Uri(string.Format(uriTemplate, entity)); 
     var request = WebRequest.Create(uri); 
     string result; 

     using (var response = (HttpWebResponse)await request.GetResponseAsync().ConfigureAwait(false)) 
     { 
      var reader = new StreamReader(response.GetResponseStream())) 
      result = await (string) reader.ReadToEndAsync().ConfigureAwait(false); 
     } 

     return result; 

} 

Как было упомянуто в комментариях, не забудьте утилизировать выделенные ресурсы, такие как WebResponse.

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