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); }