2014-01-21 3 views
5

Целью приведенного ниже метода является асинхронная настройка и запуск сообщения http из приложения для настольных компьютеров в веб-контроллер. Я думаю, что проблема в том, как мы настраиваем задачу ниже, и я считаю, что в .NET 4.5 есть лучшие методы, такие как async/await и Task.Run, которые будут решать проблему, но обновление в настоящее время не является вариант. Есть ли лучший способ обработать/записать это в .NET 4.0, чтобы предотвратить описанные ниже проблемы?PostAsync() в рамках задачи в .NET 4.0, вызывающей WebException

public void PostWithoutResponse(object objectToPost, string url) { 
     Task.Factory.StartNew(() => 
     { 
      using (var handler = new HttpClientHandler()) { 
       handler.PreAuthenticate = true; 
       handler.Credentials = _credentialPool.GetNetworkCredentials(new Uri(url)); 
       using (var client = new HttpClient(handler)) { 
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
        using (var stringContent = new StringContent(JsonConvert.SerializeObject(objectToPost), Encoding.UTF8, "application/json")) { 
         // We weren't able to get this post to work without waiting for result 
         var result = client.PostAsync(url, stringContent).Result; 
        } 
       } 
      } 
     }); 
    } 

Этот метод иногда будет работать только в 2-3 раза, а иногда и несколько, а иногда даже работает на сотни постов - несколько партий - до неудачу. Программа продолжается, но никакие дальнейшие сообщения не отражаются в базе данных, и в итоге создается исключение. (. Возможно, из-за тайм-аута)

Мы имели возможность наблюдать это исключение бросают:

System.AggregateException was unhandled 
Message: An unhandled exception of type 'System.AggregateException' occurred in mscorlib.dll 
Additional information: One or more errors occurred. 

С одним внутренним исключением:

_innerException {"The request was canceled"} System.Exception {System.Net.WebException} 

Интересно, что хотя обновления базы данных остановки после 2-3, программа (рабочий процесс автоматической обработки партии) продолжает работать, и исключение, похоже, не выбрасывается до тех пор, пока этот метод не будет достигнут для получения новой партии. Возможно, связано?

public string GetPostResult(object objectToPost, string url) { 
     string jsonResult = null; 
     using (var handler = new HttpClientHandler()) { 
      handler.PreAuthenticate = true; 
      handler.Credentials = _credentialPool.GetNetworkCredentials(new Uri(url)); 
      using (var client = new HttpClient(handler)) { 
       client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
       var serializedContent = JsonConvert.SerializeObject(objectToPost); 
       using (var stringContent = new StringContent(serializedContent, Encoding.UTF8, "application/json")) { 
        var taskResult = client.PostAsync(url, stringContent).Result; 
        jsonResult = taskResult.Content.ReadAsStringAsync().Result; 
       } 
      } 
     } 
     return jsonResult; 
    } 

Кроме того, я должен отметить, что мы пытались положить Try/улов в несколько соглашений, но не могу показаться, чтобы захватить это исключение в любом месте до тех пор, пока пузырьки, и ломает выполнения.

(Изначально казалось, что приведенный выше код работает на наших компьютерах развития, а при отсутствии на производственных машинах, но оказывается, были случайные удачи в сочетании с непониманием с нашей стороны.)

+0

Похоже, что вы можете слишком быстро нанести удар по серверу и ограничить скорость. –

+0

Оцените эту мысль, но не объясните, почему она работает отлично на наших машинах с той же скоростью. – RJB

+0

@RJB, поскольку IIS, установленный на ваших компьютерах, не имеет ограничения скорости? –

ответ

2

Этот код кажется чтобы решить эту проблему .....

public void PostWithoutResponse(object objectToPost, string url) { 
     var uri = new Uri(url); 
     var httpPost = (HttpWebRequest)WebRequest.Create(uri); 
     httpPost.KeepAlive = false; 
     httpPost.Method = "POST"; 
     httpPost.Credentials = _credentialPool.GetNetworkCredentials(uri); 
     httpPost.ContentType = "application/json"; 
     using (var streamWriter = new StreamWriter(httpPost.GetRequestStream())) { 
      var json = JsonConvert.SerializeObject(objectToPost); 
      streamWriter.Write(json); 
      streamWriter.Flush(); 
      streamWriter.Close(); 
     } 
     Task.Factory.StartNew(() => httpPost.GetResponse()); 
    } 
+0

RJB, вы уверены, что последняя строка не должна быть просто 'return httpPost.GetResponse()', без 'Task.Factory.StartNew'? – Noseratio

+0

Сначала пробовал это так, метод блокировал синхронно на '.GetResponse()', это более удобный огонь и забыть. До сих пор он работал на несколько тысяч должностей. – RJB

+0

.... хотя аргумент может быть сделан, возможно, для 'Task.Factory.FromAsync (httpPost.BeginGetResponse, httpPost.EndGetResponse, null);' Hmmm. – RJB

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