Получение HttpClient для POST / PUT Async - PullRequest
0 голосов
/ 31 августа 2018

Я пытаюсь PUT и POST к URL-адресу, используя HttpClient в C #. Мне нужно сделать это асинхронно для масштабирования. Тем не менее, я могу только заставить мои PUT и POST работать синхронно. Ниже приведен код, который я использую для переноса объектов ZoomData в формате JSON на URL:

// takes the dataset to PUT and PUTs to server
    public async Task<HttpResponseMessage> JsonPUTcall(ZoomData toPut)
    {
        string jsonString = JsonConvert.SerializeObject(toPut);
        return await client.PutAsync(InsiteDatasetPutURL.Replace("sys_id", toPut.sys_id), new StringContent(jsonString, UnicodeEncoding.UTF8, "application/json"));
    }

А вот код, который я использую для фактической передачи объектов ZoomData в очередь в JsonPUTcall:

public async void JsonPUTqueueCall(Queue<ZoomData> toPut)
    {
        if (toPut.Count == 0)
            return;
        foreach (var zoomData in toPut)
        {
            var result = await this.JsonPUTcall(zoomData);                                
        }
    }

Однако, когда я пытаюсь это сделать, он просто зависает. Итак, в качестве теста я заменил «var result = await this.JsonPUTcall (zoomData);» со следующим:

public async void JsonPUTqueueCall(Queue<ZoomData> toPut)
    {
        if (toPut.Count == 0)
            return;
        foreach (var zoomData in toPut)
        {
            var result = this.JsonPUTcall(zoomData);
            result.Wait();                                
        }
    }

Это работает, но, поскольку оно является синхронным, оно побеждает цель использования async. Чего мне не хватает?

Ответы [ 2 ]

0 голосов
/ 20 октября 2018

Эти две строки должны сделать его синхронным:

var result = this.JsonPUTcall(zoomData);
 result.Wait();      

Чтобы сделать это асинхронным, вы ненавидите это делать:

var result = await this.JsonPUTcall(zoomData);
0 голосов
/ 04 сентября 2018

это мой клиент API, который эффективно использует ресурсы и методы асинхронны

using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
//You need to install package Newtonsoft.Json > https://www.nuget.org/packages/Newtonsoft.Json/
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;


public class MyApiClient : IDisposable
{
    private readonly TimeSpan _timeout;
    private HttpClient _httpClient;
    private HttpClientHandler _httpClientHandler;
    private readonly string _baseUrl;
    private const string ClientUserAgent = "my-api-client-v1";
    private const string MediaTypeJson = "application/json";

    public MyApiClient(string baseUrl, TimeSpan? timeout = null)
    {
        _baseUrl = NormalizeBaseUrl(baseUrl);
        _timeout = timeout ?? TimeSpan.FromSeconds(90);
    }

    public async Task<string> PostAsync(string url, object input)
    {
        EnsureHttpClientCreated();

        using (var requestContent = new StringContent(ConvertToJsonString(input), Encoding.UTF8, MediaTypeJson))
        {
            using (var response = await _httpClient.PostAsync(url, requestContent))
            {
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync();
            }
        }
    }

    public async Task<TResult> PostAsync<TResult>(string url, object input) where TResult : class, new()
    {
        var strResponse = await PostAsync(url, input);

        return JsonConvert.DeserializeObject<TResult>(strResponse, new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        });
    }

    public async Task<TResult> GetAsync<TResult>(string url) where TResult : class, new()
    {
        var strResponse = await GetAsync(url);

        return JsonConvert.DeserializeObject<TResult>(strResponse, new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        });
    }

    public async Task<string> GetAsync(string url)
    {
        EnsureHttpClientCreated();

        using (var response = await _httpClient.GetAsync(url))
        {
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }
    }

    public async Task<string> PutAsync(string url, object input)
    {
        return await PutAsync(url, new StringContent(JsonConvert.SerializeObject(input), Encoding.UTF8, MediaTypeJson));
    }

    public async Task<string> PutAsync(string url, HttpContent content)
    {
        EnsureHttpClientCreated();

        using (var response = await _httpClient.PutAsync(url, content))
        {
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }
    }

    public async Task<string> DeleteAsync(string url)
    {
        EnsureHttpClientCreated();

        using (var response = await _httpClient.DeleteAsync(url))
        {
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }
    }

    public void Dispose()
    {
        _httpClientHandler?.Dispose();
        _httpClient?.Dispose();
    }

    private void CreateHttpClient()
    {
        _httpClientHandler = new HttpClientHandler
        {
            AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
        };

        _httpClient = new HttpClient(_httpClientHandler, false)
        {
            Timeout = _timeout
        };

        _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(ClientUserAgent);

        if (!string.IsNullOrWhiteSpace(_baseUrl))
        {
            _httpClient.BaseAddress = new Uri(_baseUrl);
        }

        _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeJson));
    }

    private void EnsureHttpClientCreated()
    {
        if (_httpClient == null)
        {
            CreateHttpClient();
        }
    }

    private static string ConvertToJsonString(object obj)
    {
        if (obj == null)
        {
            return string.Empty;
        }

        return JsonConvert.SerializeObject(obj, new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        });
    }

    private static string NormalizeBaseUrl(string url)
    {
        return url.EndsWith("/") ? url : url + "/";
    }
}

Usage ;

using ( var client = new MyApiClient("http://localhost:8080"))
{
    var response = client.GetAsync("api/users/findByUsername?username=alper").Result;
    var userResponse = client.GetAsync<MyUser>("api/users/findByUsername?username=alper").Result;
}
...