创建一个安全线程的客户端库以连接到外部API

时间:2016-04-01 09:37:14

标签: c# multithreading dotnet-httpclient

很抱歉我的帖子名称,但我会尝试解释我的问题。

我正在构建一个客户端库来请求外部API,我试图弄清楚如何使我的库的方法安全线程。

基本上我的库的主要类看起来像这样:

public class MyCompanyApiClient
{
    private readonly HttpClient _httpClient;

    public MyCompanyApiClient(string baseUrl)
    {
        _httpClient = new HttpClient() {BaseAddress = new Uri(baseUrl)};
        _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }

    public async Task<MyClassB> PostData(int id, MyClassA dataToPost)
    {
        var request = new HttpRequestMessage(HttpMethod.Post, $"objects/{id}");
        request.Content = new StringContent(JsonConvert.SerializeObject(dataToPost), Encoding.UTF8,
            "application/json");

        var response = await _httpClient.SendAsync(request);
        response.EnsureSuccessStatusCode();

        var stringContent = await response.Content.ReadAsStringAsync();
        return JsonConvert.DeserializeObject<MyClassB>(stringContent);
    }

    public async Task<MyClassA > GetById(int id)
    {
         ...
    }
}

我想确保我的客户端类的任何实例成员都是安全线程的。

目前我计划将每个方法中的代码包装到Task.Run

public async Task<MyClassB> PostData(int id, MyClassA dataToPost)
{
    return await Task.Run(async () =>
    {
        var request = new HttpRequestMessage(HttpMethod.Post, $"objects/{id}");
        request.Content = new StringContent(JsonConvert.SerializeObject(dataToPost), Encoding.UTF8,
            "application/json");

        var response = await _httpClient.SendAsync(request);
        var stringContent = await response.Content.ReadAsStringAsync();
        return JsonConvert.DeserializeObject<MyClassB>(stringContent);
    });
}

顺便说一下,我甚至不知道是否要确保这种方法是安全线程的。

任何帮助得到了回报^^

1 个答案:

答案 0 :(得分:2)

线程安全并不意味着多线程

这意味着某些代码知道它将在多线程情况下使用,并且它们不会被破坏,不会产生死锁和其他与线程相关的问题。

有时代码本身就是线程安全的 ,有时您需要使用线程同步方法,如监视器,互斥锁,重置事件,信号量等,以保护关键代码段不被一个,两个或 n 线程同时执行,以便再次避免死锁,损坏和基本上意外的行为。

在您的情况下,您似乎认为线程安全在线程池中启动PostData作为线程。这是一个糟糕的选择,你不需要一个新的线程。