代码改变世界

一个简单的利用 HttpClient 异步下载的示例

2018-09-09 16:46  音乐让我说  阅读(640)  评论(0编辑  收藏  举报

可能你还会喜欢 一个简单的利用 WebClient 异步下载的示例  ,且代码更加新。

1. 定义自己的 HttpClient 类。

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace WindowsFormsApplication1.Codes
{
    public class SkyHttpClient
    {
        HttpClient client;

        public string BaseURL { get; }

        public SkyHttpClient()
            :this(string.Empty)
        {
            
        }

        public SkyHttpClient(string baseUrl)
        {
            this.BaseURL = baseUrl;
            InitializeClient();
        }

        public async Task<byte[]> DownloadImage(string url)
        {
            return await client.GetByteArrayAsync(url);
        }

        void InitializeClient()
        {
            client = new HttpClient();
            if (!string.IsNullOrEmpty(BaseURL))
            {
                client.BaseAddress = new Uri(BaseURL);
                client.DefaultRequestHeaders.Add("Referer", BaseURL);
                client.DefaultRequestHeaders.Add("Origin", BaseURL);
            }
            client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36");
            
            //client.DefaultRequestHeaders.Add("Accept", "application/json");
        }
    }
}

 

2. 完成核心下载方法。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace WindowsFormsApplication1.Codes
{
     public static class TaskDemo101
    {
        public static async Task<bool> RunCore(int id)
        {
            SkyHttpClient skyHttpClient = new SkyHttpClient();

            string url1 = "http://www.xxx.me/Uploads/image/20130129/2013012920080761761.jpg";
            string url2 = "http://www.xxx.me/Uploads/image/20121222/20121222230686278627.jpg";
            string url3 = "http://www.xxx.me/Uploads/image/20120606/20120606222018461846.jpg";
            string url4 = "http://www.xxx.me/Uploads/image/20121205/20121205224383848384.jpg";
            string url5 = "http://www.xxx.me/Uploads/image/20121205/20121205224251845184.jpg";

            string resultUrl;
            int randomNum = new Random().Next(1, 6);
            switch (randomNum)
            {
                case 1: resultUrl = url1; break;
                case 2: resultUrl = url2; break;
                case 3: resultUrl = url3; break;
                case 4: resultUrl = url4; break;
                case 5: resultUrl = url5; break;
                default: throw new Exception("");
            }
            var task = skyHttpClient.DownloadImage(resultUrl);
            return await task.ContinueWith<bool>(t => {
                var data = t.Result;
                string targetFolderDestination = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "downloads\\images\\");
                try
                {
                    Directory.CreateDirectory(targetFolderDestination);
                }
                catch (Exception)
                {
                    Console.WriteLine("创建文件夹失败!");
                    return false;
                }
                string targetFileDestination = Path.Combine(targetFolderDestination, string.Format("img_{0}.png", DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")));
                File.WriteAllBytes(targetFileDestination, data);
                return true;
            });
        }
    }
}

 

3. 制作 UI

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            try
            {
                List<int> ids = new List<int>(100);
                for (int i = 1; i <= 100; i++)
                {
                    ids.Add(i);
                }
                this.listBoxLog.Items.Insert(0, string.Format("当前时间:{0},准备开始下载...", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
                foreach (var id in ids)
                {
                    bool result = await TaskDemo101.RunCore(id);
                    this.listBoxLog.Items.Insert(0, string.Format("当前时间:{0},编号 {1} 下载 {2}!", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), id, result));
                }
                this.listBoxLog.Items.Insert(0, string.Format("当前时间:{0},下载完毕!", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Download Error!");
            }
        }
    }

 

4. 运行截图

 

5. 疑问

最后,需要注意的是我们的 SkyHttpClient 是每次下载一个图片都会创建一个,那这种每次创建销毁是否会有性能影响呢?在单线程的环境下,我们能否通过外部传入 SkyHttpClient 呢?

比如如下:

6. 最后

参考了文章 https://www.oschina.net/news/77036/httpclient 发现 HttpClient 建议不要每次都创建新的,而尽量要 static 全局变量缓存,但多线程下也许不安全,所以需要注意最好一个线程使用一个 HttpClient。

还有这篇文章:https://www.cnblogs.com/MingQiu/p/7728443.html

 

谢谢浏览!