У меня есть этот сценарий, я работаю над тем, где нужно отправить уведомление на все рабочие станции в моей компании. У нас есть клиентская служба, которая обрабатывает уведомления на рабочем столе, и это очень простой WebApi.
Вопрос / требование Как мне одновременно и в асинхронном, и в параллельном режиме отправить запрос на все эти машины из веб-приложения сервера / ASP.Net и записать его ответ в настраиваемый файл журнала?
Многие машины могут быть выключены во время отправки уведомления, или DNS может быть не в состоянии разрешить, поскольку машина могла быть выведена из эксплуатации.
Цикл запроса / ответа на код, который в настоящее время прототипируется, должен быть неблокирующим. Так что пользователю не придется ждать ответа от всех этих машин.
Моя домашняя работа: Я понимаю, что асинхронные операции лучше подходят для операций с привязкой к вводу-выводу, однако количество машин настолько велико, что я чувствую параллельность и асинхронность вместе, может лучше подойти для этой ситуации.
Я установил ServicePointManager.DefaultConnectionLimit = 10000
HttpClient с конструктором с параметром dispose равным false был передан. См. Ниже код - Заводской класс.
Класс HttpClient в структуре предназначен для повторного использования, однако, насколько я понимаю, некоторые свойства не могут быть изменены, например, базовый адрес. Источник: HttpClient - этот экземпляр уже запущен
Я использую конкретный идентификатор запроса / ответа (идентификатор корреляции), чтобы убедиться, что все асинхронные и параллельные операции выполняются в одной и той же папке для данного запроса.
Блок перехвата TaskCanceledException никогда не срабатывает !!
Таймаут увеличен до 30 секунд, что, я уверен, более чем достаточно.
Код прототипа:
public class HttpClientFactory : IHttpClientFactory
{
public void CreateClient(string baseUrl, Action<HttpClient> methodToExecute)
{
using (var handler = new HttpClientHandler())
{
handler.AllowAutoRedirect = true;
using (var client = new HttpClient(handler, false))
{
client.BaseAddress = new Uri(baseUrl);
client.Timeout = TimeSpan.FromSeconds(30);
methodToExecute(client);
}
}
}
}
Где IHttpClientFactory - временный (IoC)
workstationUrls.ForEach(baseUrl =>
{
_httpClientFactory.CreateClient(baseUrl, async (client) =>
{
await client.PostAsync(resourceUrl, content).ContinueWith(t =>
{
try
{
var response = t.Result;
var workstationResponse = new WorkstationResponse
{
StatusCode = (int)response.StatusCode,
Response = response.Content.ReadAsStringAsync().Result
};
workstationResponse.IsSuccess
= workstationResponse.StatusCode >= 200 &&
workstationResponse.StatusCode <= 299
? true
: false;
var docContent = JsonConvert.SerializeObject(workstationResponse);
if (workstationResponse.IsSuccess)
{
// Write workstation log
File.WriteAllText(path
+ "\\Bulk Notifications\\"
+ userFolder + "\\Success\\"
+ GetWorkstationNameFromUrl(baseUrl)
+ GetUniqueTimeStampForFileNames()
+ workstationResponse.IsSuccess + ".txt",
docContent);
}
else
{
// Write workstation log
File.WriteAllText(path
+ "\\Bulk Notifications\\"
+ userFolder + "\\Fail\\"
+ GetWorkstationNameFromUrl(baseUrl)
+ GetUniqueTimeStampForFileNames()
+ workstationResponse.IsSuccess + ".txt",
docContent);
}
}
catch (TaskCanceledException exe)
{
}
catch (Exception ex)
{
var workstationResponse = new WorkstationResponse
{
Exception = ex,
IsSuccess = false
};
var docContent = JsonConvert.SerializeObject(workstationResponse);
// Write workstation log
File.WriteAllText(path
+ "\\Bulk Notifications\\"
+ userFolder + "\\Fail\\"
+ GetWorkstationNameFromUrl(baseUrl) + " "
+ GetUniqueTimeStampForFileNames() + " "
+ workstationResponse.IsSuccess + ".txt", docContent);
}
});
});
});
Проблема с кодом прототипа: я получаю эти ошибки в сообщениях об исключениях, и StackTrace не кажется мне полезным.
- «Задача была отменена»
- «Невозможно получить доступ к удаленному объекту. Имя объекта: 'System.Net.Http.StringContent'»
Action<HttpClient> methodToExecute
на функцию, которая возвращает задачу, чтобы вы могли дождаться асинхронных методов, которые правильно взаимодействуют сHttpClient
. Это вызывает удаленное исключение. - person Peter Bons   schedule 17.09.2017