1

我有一个自定义 API 客户端调用具有许多控制器的自定义 API 服务。我实际上有这个类:

public abstract class APIClientBase
{
    protected HttpClient _httpClient;

    public APIClientBase()
    {
        _httpClient = new HttpClient();
        _httpClient.BaseAddress = new Uri("https://localhost:44369/");
    }
}

这是由许多像这样的类实现的:

public class APIClientEmployee : APIClientBase
{
    public async Task<ObservableCollection<Employee>> GetAllEmployeesRequestAsync()
    {
        ObservableCollection<Employee> employees = null;
        HttpResponseMessage response = await _httpClient.GetAsync($"api/employees");

        if (response.IsSuccessStatusCode)
        {
            employees = response.Content.ReadAsAsync<ObservableCollection<Employee>>().Result;
        }

        return employees;
    }

    public ObservableCollection<Employee> GetAllVeterinaryEmployeesRequest()
    {
        ObservableCollection<Employee> employees = null;
        HttpResponseMessage response = _httpClient.GetAsync($"api/employees/veterinaryemployees").Result;

        if (response.IsSuccessStatusCode)
        {
            employees = response.Content.ReadAsAsync<ObservableCollection<Employee>>().Result;
        }

        return employees;
    }

    public async Task<Employee> GetSingleEmployeeRequestAsync(int id)
    {
        Employee employee = null;
        HttpResponseMessage response = await _httpClient.GetAsync($"api/employees/{id}");

        if (response.IsSuccessStatusCode)
        {
            employee = response.Content.ReadAsAsync<Employee>().Result;
        }

        return employee;
    }

    public Employee GetSingleEmployeeRequest(int id)
    {
        Employee employee = null;
        HttpResponseMessage response = _httpClient.GetAsync($"api/employees/{id}").Result;

        if (response.IsSuccessStatusCode)
        {
            employee = response.Content.ReadAsAsync<Employee>().Result;
        }

        return employee;
    }

    public async Task PutSingleEmployeeRequestAsync(Employee employee)
    {
        HttpResponseMessage response = await _httpClient.PutAsJsonAsync($"api/employees/{employee.EmployeeID}", employee);
        response.EnsureSuccessStatusCode();
    }

    public async Task PostSingleEmployeeRequestAsync(Employee employee)
    {
        HttpResponseMessage response = await _httpClient.PostAsJsonAsync($"api/employees", employee);
        response.EnsureSuccessStatusCode();
    }

    public async Task DeleteSingleEmployeeRequestAsync(int id)
    {
        HttpResponseMessage response = await _httpClient.DeleteAsync($"api/employees/{id}");
        response.EnsureSuccessStatusCode();
    }
}

我在我的 ViewModels 中像这样使用它们:

 public class EmployeeListViewModel
 {
    private APIClientEmployee _apiClientEmployee;

    private ObservableCollection<Employee> _employees;

    public ObservableCollection<Employee> Employees
    {
        get
        {
            return _employees;
        }
        set
        {
            _employees = value;
            OnPropertyChanged("Employees");
        }
    }

    public EmployeeListViewModel()
    {
        _apiClientEmployee = new APIClientEmployee();
        FillEmployeeList();
    }

    public async void FillEmployeeList()
    {
        Employees = await _apiClientEmployee.GetAllEmployeesRequestAsync();
    }
}

我在很多地方都做这样的事情。此外,我在其他 ViewModel 中创建了其他 APIClientEmployee,因为我在其他一些地方需要员工数据。但是这种方法让我创建了许多 APIClient 对象/Http 客户端,我觉得我这样做的方式有问题。我想我可以打破我的套接字限制或类似的东西,然后它会导致问题。我已经阅读了很多教程,但它们通常并不复杂。我应该只有一个类,其中包含每个 API 调用吗?我应该用我的每个 APIClient 类的一个实例来实现一个单例吗?我不知道该怎么做,我想有建议...

4

1 回答 1

1

你说的很对。查看HttpClient的官方文档:

HttpClient 旨在被实例化一次并在应用程序的整个生命周期中重复使用。为每个请求实例化一个 HttpClient 类将耗尽重负载下可用的套接字数量。这将导致 SocketException 错误。下面是一个正确使用 HttpClient 的例子。

这就是它的声明方式

static readonly HttpClient client = new HttpClient();

您可以执行以下操作:

public abstract class APIClientBase
{
    protected static readonly HttpClient client = new HttpClient();

然后像这样使用:

HttpResponseMessage response = await APIClientBase.client.GetAsync($"api/employees/{id}");
于 2020-02-11T16:00:46.360 回答