Fork me on GitHub

NET 并发编程

场景并发调用API

 

1、简单封装httpclient

 

 public class CommonHelper
    {
        private static readonly HttpClient _httpClient;

        static CommonHelper()
        {
            _httpClient = new HttpClient();
            _httpClient.DefaultRequestHeaders.Connection.Add("keep-alive");
        }

        public static async Task<T> PostAsync<T>(string url, object request)
        {
            var response = await _httpClient.PostAsJsonAsync(url, request);

            return await response.Content.ReadAsAsync<T>();
        }
    }

 

可参考:http://www.cnblogs.com/dudu/p/csharp-httpclient-attention.html

 

 

2、简单api服务

 public class ValuesController : ApiController
    {
        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }

    
        // POST api/values
        public string Post([FromBody]string value)
        {
            return value;
            
        }

        // PUT api/values/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/values/5
        public void Delete(int id)
        {
        }
    }

3、for循环调用:

_httpClient.PostAsJsonAsync是线程安全的,通过打印结果可以看出:

 

            Dictionary<int, Task<string>> tasks = new Dictionary<int, Task<string>>();
            for (int i = 0; i < 10; i++)
            {
                tasks.Add(i, CommonHelper.PostAsync<string>(url, "test" + i));
            }


            foreach (var task in tasks)
            {
                Console.WriteLine(task.Key + "" + task.Value.Result);
            }

 

 

 

4、并发调用,

Dictionary中字典肯定会报异常,因为它不是线程安全的;

 

 

  Parallel.For(0, 100, (i) =>
            {
                Console.WriteLine(i);
               
                tasks.Add(i, CommonHelper.PostAsync<string>(url, "test" + i));
            });

 

5、采用 Queue 或是 ConcurrentDictionary

 

 var queue = new Queue<Task<string>>();
            var dic = new ConcurrentDictionary<int, Task<string>>();
            Parallel.For(0, 100, (i) =>
            {
                Console.WriteLine(i);
                queue.Enqueue( CommonHelper.PostAsync<string>(url, "test" + i));
                
            });
      
            while (true)
            {
                if (dic.Count > 0)
                {
                    var value = queue.Dequeue();
                    Console.WriteLine(value.Result);
                }
            }

Queue可以作为生产者、消费者模式使用:参考  http://www.cnblogs.com/chengxiaohui/articles/5672768.html

 

ConcurrentDictionary方式:

 var queue = new Queue<Task<string>>();
            var dic = new ConcurrentDictionary<int, Task<string>>();
            Parallel.For(0, 100, (i) =>
            {
                Console.WriteLine(i);
                //queue.Enqueue( CommonHelper.PostAsync<string>(url, "test" + i));
                dic.TryAdd(i, CommonHelper.PostAsync<string>(url, "test" + i));
            });
            
            foreach (var item in dic)
            {
                Console.WriteLine(item.Key + "" + item.Value.Result);
            }

 

posted @ 2017-04-09 19:17  迁梦余光  阅读(219)  评论(0编辑  收藏  举报