KGBRS Ответов: 1

Использование webapi из SSIS scripttask с помощью webclient работает не так, как ожидалось.


Всем Привет,
Я потребляю WebAPI из пакетов SSIS, поэтому я написал следующий код в ScriptTask, и мое намерение состоит в том, чтобы дождаться ответа (т. е. он просто вызовет конечную точку и продолжит процесс)

var webClient = new System.Net.WebClient();
webClient.Headers.Add("abc", "xyz");
webClient.Headers.Add("abc1", "xyz1");

File.AppendAllLines("FilePath\\Log.txt", new string[] { string.Format("{0}  EP Calling Started: {1}", DateTime.Now, BatchID) });
System.Collections.Specialized.NameValueCollection formData = new System.Collections.Specialized.NameValueCollection();
formData["test"] = "test";
webClient.UploadValuesAsync(new Uri(webAddr), "Post", formData);
File.AppendAllLines("FilePath\\Log.txt",, new string[] { string.Format("{0} EP Calling ended: {1}", DateTime.Now, BatchID) });

Иногда WebClient не попадает в конечную точку. чтобы подтвердить, что я поместил ведение журнала текстового файла в задачу скрипта и конечную точку. вызов конечной точки происходит из пакетов, но он не попадает в конечную точку в журналах, которые я нашел
when WebClient is not hitting the endpoint. following info is logged into the file
From Script Task:
6/1/2017 1:10:03 PM EP Calling Started: 33962
6/1/2017 1:10:03 PM EP Calling ended: 33962

если это успех журнал будет выглядеть так
From Script Task:
6/1/2017 1:10:03 PM EP Calling Started: 33962
6/1/2017 1:10:03 PM EP Calling ended: 33962
From endPoint:
6/1/2017 1:10:04 PM EP Started: 33962
6/1/2017 1:10:58 PM EP ended: 33962


не могли бы вы сообщить мне, в чем заключается основная причина этой проблемы?

Что я уже пробовал:

var webClient = new System.Net.WebClient();
webClient.Headers.Add("abc", "xyz");
webClient.Headers.Add("abc1", "xyz1");

File.AppendAllLines("FilePath\\Log.txt", new string[] { string.Format("{0}  EP Calling Started: {1}", DateTime.Now, BatchID) });
System.Collections.Specialized.NameValueCollection formData = new System.Collections.Specialized.NameValueCollection();
formData["test"] = "test";
webClient.UploadValuesAsync(new Uri(webAddr), "Post", formData);
File.AppendAllLines("FilePath\\Log.txt",, new string[] { string.Format("{0} EP Calling ended: {1}", DateTime.Now, BatchID) });

1 Ответов

Рейтинг:
4

Richard Deeming

UploadValuesAsync[^] не дожидается завершения запроса. Он запускает фоновую операцию для выполнения запроса и немедленно возвращается. Когда запрос будет завершен, UploadValuesCompleted[^] событие будет поднято.

Ваш метод, скорее всего, завершится до того, как запрос будет завершен, потому что он не ждет ответа. UploadValuesCompleted событие.

Если вы хотите сделать синхронный запрос, используйте UploadValues[^] метод вместо этого.

Если вам все еще нужен асинхронный запрос, но вы хотите дождаться завершения запроса до выхода вашего метода, то вам нужно будет использовать что-то вроде ManualResetEvent ждать, пока UploadValuesCompleted пожары событий.

var mre = new ManualResetEventSlim();
webClient.UploadValuesCompleted += delegate { mre.Set(); };
webClient.UploadValuesAsync(new Uri(webAddr), "Post", formData);
...
mre.Wait();


KGBRS

Привет Ричард Диминг,
Спасибо вам за ваше решение, оно было очень полезно для меня.
но пока я попробовал по-другому с классом httpClient.

Скрыть   скопировать код

 
var hc = new HttpClient();
hc.DefaultRequestHeaders.Add("Key1", Value1);
hc.DefaultRequestHeaders.Add("Key2", Value2); 
var request = new HttpRequestMessage(HttpMethod.Post, webAddr);
var response = hc.SendAsync(request);


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

Richard Deeming

Да, это тот же самый вопрос - SendAsync метод возвращает до запрос завершен.

В этом случае метод возвращает Task, так что решение немного другое.

Если вы можете сделать вызывающий метод async, тогда вам нужно await возвращенная задача:
Асинхронное программирование[^]

Но поскольку вы звоните сюда из Службы безопасности, вы, вероятно, не можете этого сделать. Вместо этого вам нужно будет заблокировать поток до тех пор, пока запрос не будет завершен:

var response = hc.SendAsync(request).GetAwaiter().GetResult();

Если вы хотите зеркально отразить WebClient код и выдать исключение, если сервер ответит ошибкой, вам нужно будет вызвать:
response.EnsureSuccessStatusCode();

KGBRS

Спасибо, Ричард Диминг.