C# WebClient.DownloadFile下载后如何释放WebClient

先贴上完整的代码

[HttpPost]
        [HandlerAjaxOnly]
        public ActionResult export(string cp_fbill, string cp_sn)
        {
            string sql = "select * from customer_complaint_sp_file where cp_fbill='" + cp_fbill + "' and cp_sn=" + cp_sn + "";
            DataTable dt0 = DbHelperSQL.Query(sql).Tables[0];
            //获取客诉单单身customer_complaint_e_file的信息
            sql = "select * from customer_complaint_e_file where cp_e_fbill='" + cp_fbill + "' and cp_e_sn=" + cp_sn + "";
            DataTable dte = DbHelperSQL.Query(sql).Tables[0];

            //获取客诉单单头customer_complaint_h_file的信息
            sql = "select * from customer_complaint_h_file where cp_h_fbill='" + cp_fbill + "' ";
            DataTable dth = DbHelperSQL.Query(sql).Tables[0];


            sql = "select * from customer_complaint_sp_d1_file where cp_sr_fbill='" + cp_fbill + "' and cp_sr_d1_sn=" + cp_sn + "";
            DataTable dt1 = DbHelperSQL.Query(sql).Tables[0];
            dt1.TableName = "d1";
            sql = "select * from customer_complaint_sp_d2_file where cp_sr_fbill='" + cp_fbill + "' and cp_sr_d2_sn=" + cp_sn + "";
            DataTable dt2 = DbHelperSQL.Query(sql).Tables[0];
            dt2.TableName = "d2";
            sql = "select * from customer_complaint_sp_d3_file where cp_sr_fbill='" + cp_fbill + "' and cp_sr_d3_sn=" + cp_sn + "";
            DataTable dt3 = DbHelperSQL.Query(sql).Tables[0];
            dt3.TableName = "d3";
            sql = "select * from customer_complaint_sp_d4_file where cp_sr_fbill='" + cp_fbill + "' and cp_sr_d4_sn=" + cp_sn + "";
            DataTable dt4 = DbHelperSQL.Query(sql).Tables[0];
            dt4.TableName = "d4";
            sql = "select * from customer_complaint_sp_d5_file where cp_sr_fbill='" + cp_fbill + "' and cp_sr_d5_sn=" + cp_sn + "";
            DataTable dt5 = DbHelperSQL.Query(sql).Tables[0];
            dt5.TableName = "d5";
            sql = "select * from customer_complaint_sp_d6_file where cp_sr_fbill='" + cp_fbill + "' and cp_sr_d6_sn=" + cp_sn + "";
            DataTable dt6 = DbHelperSQL.Query(sql).Tables[0];
            dt6.TableName = "d6";
            sql = "select * from customer_complaint_sp_d7_file where cp_sr_fbill='" + cp_fbill + "' and cp_sr_d7_sn=" + cp_sn + "";
            DataTable dt7 = DbHelperSQL.Query(sql).Tables[0];
            dt7.TableName = "d7";
            sql = "select * from customer_complaint_sp_d8_file where cp_sr_fbill='" + cp_fbill + "' and cp_sr_d8_sn=" + cp_sn + "";
            DataTable dt8 = DbHelperSQL.Query(sql).Tables[0];
            dt8.TableName = "d8";

            WorkbookDesigner designer = new WorkbookDesigner();
            designer.Open(Server.MapPath("~/Content/template/客诉8D报告导出.xlsx"));

            Dictionary<string, string> dict = new Dictionary<string, string>();
            if (dt0.Rows.Count > 0)
            {
                designer.SetDataSource("cp_fbill", dt0.Rows[0]["cp_fbill"] == DBNull.Value ? "" : dt0.Rows[0]["cp_fbill"].ToString());
                designer.SetDataSource("cp_sn", dt0.Rows[0]["cp_sn"] == DBNull.Value ? "" : dt0.Rows[0]["cp_sn"].ToString());
                designer.SetDataSource("cp_sr_status", dt0.Rows[0]["cp_sr_status"] == DBNull.Value ? "" : dt0.Rows[0]["cp_sr_status"].ToString());
                designer.SetDataSource("cp_sr_confirmer", dt0.Rows[0]["cp_sr_confirmer"] == DBNull.Value ? "" : dt0.Rows[0]["cp_sr_confirmer"].ToString());
                designer.SetDataSource("cp_sr_confirm_date", dt0.Rows[0]["cp_sr_confirm_date"] == DBNull.Value ? "" : dt0.Rows[0]["cp_sr_confirm_date"].ToString());
                designer.SetDataSource("cp_sr_item_code", dt0.Rows[0]["cp_sr_item_code"] == DBNull.Value ? "" : dt0.Rows[0]["cp_sr_item_code"].ToString());
                designer.SetDataSource("cp_sr_item_name", dt0.Rows[0]["cp_sr_item_name"] == DBNull.Value ? "" : dt0.Rows[0]["cp_sr_item_name"].ToString());
                designer.SetDataSource("cp_sr_item_type", dte.Rows[0]["cp_e_item_type"] == DBNull.Value ? "" : dte.Rows[0]["cp_e_item_type"].ToString());
                designer.SetDataSource("cp_e_cu_item_code", dte.Rows[0]["cp_e_cu_item_code"] == DBNull.Value ? "" : dte.Rows[0]["cp_e_cu_item_code"].ToString());
                designer.SetDataSource("cp_e_type", dte.Rows[0]["cp_e_type"] == DBNull.Value ? "" : dte.Rows[0]["cp_e_type"].ToString());
                designer.SetDataSource("cp_e_problem_desc", dte.Rows[0]["cp_e_problem_desc"] == DBNull.Value ? "" : dte.Rows[0]["cp_e_problem_desc"].ToString());
                designer.SetDataSource("cp_e_qty", dte.Rows[0]["cp_e_qty"] == DBNull.Value ? "" : dte.Rows[0]["cp_e_qty"].ToString());
                designer.SetDataSource("cp_e_refer_qty", dte.Rows[0]["cp_e_refer_qty"] == DBNull.Value ? "" : dte.Rows[0]["cp_e_refer_qty"].ToString());
                designer.SetDataSource("cp_sr_code", dt0.Rows[0]["cp_sr_code"] == DBNull.Value ? "" : dt0.Rows[0]["cp_sr_code"].ToString());
                designer.SetDataSource("cp_st_name", dt0.Rows[0]["cp_st_name"] == DBNull.Value ? "" : dt0.Rows[0]["cp_st_name"].ToString());
                designer.SetDataSource("cp_sr_reply_date", dt0.Rows[0]["cp_sr_reply_date"] == DBNull.Value ? "" : dt0.Rows[0]["cp_sr_reply_date"].ToString());
                designer.SetDataSource("F_CreatorUserId", dt0.Rows[0]["F_CreatorUserId"] == DBNull.Value ? "" : dt0.Rows[0]["F_CreatorUserId"].ToString());
                designer.SetDataSource("F_CreatorTime", dt0.Rows[0]["F_CreatorTime"] == DBNull.Value ? "" : dt0.Rows[0]["F_CreatorTime"].ToString());
                if (dt1.Rows.Count > 0)
                {
                    designer.SetDataSource("d1replyer", dt1.Rows[0]["F_CreatorUserId"] == DBNull.Value ? "" : dt1.Rows[0]["F_CreatorUserId"].ToString());
                    designer.SetDataSource("d1replytime", dt1.Rows[0]["F_CreatorTime"] == DBNull.Value ? "" : dt1.Rows[0]["F_CreatorTime"].ToString());
                }
                if (dt2.Rows.Count > 0)
                {
                    designer.SetDataSource("d2replyer", dt2.Rows[0]["F_CreatorUserId"] == DBNull.Value ? "" : dt2.Rows[0]["F_CreatorUserId"].ToString());
                    designer.SetDataSource("d2replytime", dt2.Rows[0]["F_CreatorTime"] == DBNull.Value ? "" : dt2.Rows[0]["F_CreatorTime"].ToString());
                }
                if (dt3.Rows.Count > 0)
                {
                    designer.SetDataSource("d3replyer", dt3.Rows[0]["F_CreatorUserId"] == DBNull.Value ? "" : dt3.Rows[0]["F_CreatorUserId"].ToString());
                    designer.SetDataSource("d3replytime", dt3.Rows[0]["F_CreatorTime"] == DBNull.Value ? "" : dt3.Rows[0]["F_CreatorTime"].ToString());
                }
                if (dt4.Rows.Count > 0)
                {
                    designer.SetDataSource("d4replyer", dt4.Rows[0]["F_CreatorUserId"] == DBNull.Value ? "" : dt4.Rows[0]["F_CreatorUserId"].ToString());
                    designer.SetDataSource("d4replytime", dt4.Rows[0]["F_CreatorTime"] == DBNull.Value ? "" : dt4.Rows[0]["F_CreatorTime"].ToString());
                }
                if (dt5.Rows.Count > 0)
                {
                    designer.SetDataSource("d5replyer", dt5.Rows[0]["F_CreatorUserId"] == DBNull.Value ? "" : dt5.Rows[0]["F_CreatorUserId"].ToString());
                    designer.SetDataSource("d5replytime", dt5.Rows[0]["F_CreatorTime"] == DBNull.Value ? "" : dt5.Rows[0]["F_CreatorTime"].ToString());
                }
                if (dt6.Rows.Count > 0)
                {
                    designer.SetDataSource("d6replyer", dt6.Rows[0]["F_CreatorUserId"] == DBNull.Value ? "" : dt6.Rows[0]["F_CreatorUserId"].ToString());
                    designer.SetDataSource("d6replytime", dt6.Rows[0]["F_CreatorTime"] == DBNull.Value ? "" : dt6.Rows[0]["F_CreatorTime"].ToString());
                }
                if (dt7.Rows.Count > 0)
                {
                    designer.SetDataSource("d7replyer", dt7.Rows[0]["F_CreatorUserId"] == DBNull.Value ? "" : dt7.Rows[0]["F_CreatorUserId"].ToString());
                    designer.SetDataSource("d7replytime", dt7.Rows[0]["F_CreatorTime"] == DBNull.Value ? "" : dt7.Rows[0]["F_CreatorTime"].ToString());
                }
                if (dt8.Rows.Count > 0)
                {
                    designer.SetDataSource("d8replyer", dt8.Rows[0]["F_CreatorUserId"] == DBNull.Value ? "" : dt8.Rows[0]["F_CreatorUserId"].ToString());
                    designer.SetDataSource("d8replytime", dt8.Rows[0]["F_CreatorTime"] == DBNull.Value ? "" : dt8.Rows[0]["F_CreatorTime"].ToString());
                }
            }
            else
            {

            }
            designer.SetDataSource(dt0);//添加列表数据源
            designer.SetDataSource(dt1);//添加列表数据源
            designer.SetDataSource(dt2);//添加列表数据源
            designer.SetDataSource(dt3);//添加列表数据源
            designer.SetDataSource(dt4);//添加列表数据源
            designer.SetDataSource(dt5);//添加列表数据源
            designer.SetDataSource(dt6);//添加列表数据源
            designer.SetDataSource(dt7);//添加列表数据源
            designer.SetDataSource(dt8);//添加列表数据源
            designer.Process();

            string fileName = cp_fbill + "-" + cp_sn + ".zip";
            string filePath = Server.MapPath("/Content/cpreport8D/" + fileName);
            string sourceDir = Server.MapPath("/Content/cpreport8D/" + cp_fbill + "-" + cp_sn);

            if (!Directory.Exists(sourceDir))
            {
                Directory.CreateDirectory(sourceDir);
            }
            //string reportex = Server.MapPath("/Content/cpreport8D/" + cp_fbill + "-" + cp_sn + "/") + cp_fbill + "-" + cp_sn + "客诉报告.xlsx";
            designer.Save(Server.MapPath("/Content/cpreport8D/" + cp_fbill + "-" + cp_sn + "/") + cp_fbill + "-" + cp_sn + "客诉报告.xlsx", FileFormatType.Excel2007Xlsx);
            if (System.IO.File.Exists(filePath))
            {
                System.IO.File.Delete(filePath);
            }

            sql = " SELECT*FROM customer_complaint_sp_attach_file WHERE cp_attach_fbill='" + cp_fbill + "' AND cp_attach_sn= " + cp_sn;
            DataTable dtfile = DbHelperSQL.Query(sql).Tables[0];
            for (int i = 0; i < dtfile.Rows.Count; i++)
            {
                string dir = Server.MapPath("/Content/cpreport8D/" + cp_fbill + "-" + cp_sn + "/" + dtfile.Rows[i]["cp_attach_type"].ToString());
                string fir = Server.MapPath("/Content/cpreport8D/" + cp_fbill + "-" + cp_sn + "/" + dtfile.Rows[i]["cp_attach_type"].ToString() + "/" + dtfile.Rows[i]["F_file_name"].ToString());
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
                if (System.IO.File.Exists(fir))
                {
                    System.IO.File.Delete(fir);
                }
                string sdir = Server.MapPath("/Content/upload/" + dtfile.Rows[i]["F_file_name"].ToString());


                using (WebClient webClient = new WebClient())
                {
                    webClient.DownloadFileCompleted += (sender, e) =>
                    {
                        // 下载完成后的处理,可以在这里进行文件操作
                        // 释放资源、关闭文件流等
                        webClient.Dispose();
                    };
                    webClient.DownloadFile(new Uri(dtfile.Rows[i]["cp_attach_path"].ToString()), fir);
                }

                //// 设置参数
                //HttpWebRequest request = WebRequest.Create(dtfile.Rows[i]["cp_attach_path"].ToString()) as HttpWebRequest;
                ////发送请求并获取相应回应数据
                //HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                ////直到request.GetResponse()程序才开始向目标网页发送Post请求
                //Stream responseStream = response.GetResponseStream();

                ////创建本地文件写入流
                //Stream stream = new FileStream(fir, FileMode.Create);

                //byte[] bArr = new byte[1024];
                //int size = responseStream.Read(bArr, 0, (int)bArr.Length);
                //while (size > 0)
                //{
                //    stream.Write(bArr, 0, size);
                //    size = responseStream.Read(bArr, 0, (int)bArr.Length);
                //}
                //stream.Close();
                //responseStream.Close();


            }
            ZipUtility.ZipFiles(sourceDir, filePath, "");
            return Success("/Content/cpreport8D/" + fileName);

        }
        #endregion

我在使用WebClient来下载文件到我本地上之后,下载下来的文件没法访问
问题关键代码,用了很多种下载文件的方法,都是下载下来后文件还是被一个进程使用中,没法访问


using (WebClient webClient = new WebClient())
                {
                    webClient.DownloadFileCompleted += (sender, e) =>
                    {
                        // 下载完成后的处理,可以在这里进行文件操作
                        // 释放资源、关闭文件流等
                        webClient.Dispose();
                    };
                    webClient.DownloadFile(new Uri(dtfile.Rows[i]["cp_attach_path"].ToString()), fir);
                }

                //// 设置参数
                //HttpWebRequest request = WebRequest.Create(dtfile.Rows[i]["cp_attach_path"].ToString()) as HttpWebRequest;
                ////发送请求并获取相应回应数据
                //HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                ////直到request.GetResponse()程序才开始向目标网页发送Post请求
                //Stream responseStream = response.GetResponseStream();

                ////创建本地文件写入流
                //Stream stream = new FileStream(fir, FileMode.Create);

                //byte[] bArr = new byte[1024];
                //int size = responseStream.Read(bArr, 0, (int)bArr.Length);
                //while (size > 0)
                //{
                //    stream.Write(bArr, 0, size);
                //    size = responseStream.Read(bArr, 0, (int)bArr.Length);
                //}
                //stream.Close();
                //responseStream.Close();

后续对下载下来的文件进行访问操作的时候会提示,这个文件被另一进程使用,我来来去去经过排查,应该就是这个webClient 在下载完后,它没有释放出来,但我不知道怎么才可以释放这个webClient
我在代码后面添加过webClient.Dispose()尝试去释放它,但是加了这个也没用还是同样的提示文件被另一进程使用
使用using (WebClient webClient = new WebClient()){}让他自动释放也不行,也是一样的提示被另一进程使用

后续代码访问这个文件时候,提示的错误
System.IO.IOException:“文件“D:\development230310\seagull.Web\Content\cpreport8D\CP2023080001-1\CP2023080001-1客诉报告.xlsx”正由另一进程使用,因此该进程无法访问此文件。”

在本地文件夹上删除这个文件的时候也会已经打开,没法删除

img

webClient.DownloadFileAsync
->
webClient.DownloadFile

await webClient.DownloadFileTaskAsync(new Uri(dtfile.Rows[i]["cp_attach_path"].ToString()), fir);

既然用异步就请等待他完成,如果你不等待完成就直接在后续操作文件,那么他还在下载中
同时WebClient.DownloadFileTaskAsync 是异步task,你可以直接await他
而你用的DownloadFileAsync是早期的方法,虽然也是异步,不过他的结果通知无法等待,你需要再去订阅完成事件去得到结果
事件为WebClient.DownloadFileCompleted 事件

https://learn.microsoft.com/zh-cn/dotnet/api/system.net.webclient.downloadfilecompleted?view=net-7.0

确保在下载完成后手动释放资源,异步回调中处理释放操作。

using (WebClient webClient = new WebClient())
{
    webClient.DownloadFileCompleted += (sender, e) =>
    {
        // 下载完成后的处理,可以在这里进行文件操作
        // 释放资源、关闭文件流等
    };

    webClient.DownloadFileAsync(new Uri(dtfile.Rows[i]["cp_attach_path"].ToString()), fir);
}