C# 吃一堑,长一智

Webclient DownloadDataCompleted不能回调

C# 里的WebClient,我曾经尝试使用webClient.DownloadDataCompleted += (se, ev) =>{}

进行接收文件,但是却不能触发,因为我使用了autoResetEvent进行同步线程,耗时一天,以为是异步的问题,发现没听劝,webclient只适用于.net3,弃用了。使用httpClient进行接收流文件。

httpClient使用C#.NET HttpClient 使用教程 - 我是唐青枫 - 博客园

cs 复制代码
public class WebAccess
{
    public Action? DownloadPrograssChanged;
    public Action? DownloadCompleted;

    public async Task DownloadAsync(FileModel fileModel, string localFileName,TotalProgress totalProgress)
  {
    
    using (var httpClient = new HttpClient())
    {
        DownloadCompleted += () =>
        {
            fileModel.State = "已更新";
        };

        DownloadPrograssChanged = new Action(() =>
        {
            //total_file_read = (long)(total_file_read / 1024);
            totalProgress.Progress = (int)((totalProgress.TotalReadKByte * 100) / totalProgress.TotalKByte);
            if (totalProgress.Progress >= 99)
            {
                totalProgress.Progress = 100;
            }
        });
       
        // 下载进度回调需要自己实现(HttpClient没有现成的Progress事件)
        using (var response = await httpClient.GetAsync(new Uri($"http://localhost:5003/api/file/download/{fileModel.FileName}"), HttpCompletionOption.ResponseHeadersRead))
        {
            //response.EnsureSuccessStatusCode();
            if (response.StatusCode != HttpStatusCode.OK)
            {
                throw new Exception("服务器获取更新文件异常");
            }
            var totalBytes = response.Content.Headers.ContentLength ?? 0;
            using (var stream = await response.Content.ReadAsStreamAsync())
            {

                using (var fileStream = new FileStream(localFileName, FileMode.Create))
                {
                    var buffer = new byte[8192];//8kb
                    long totalRead = 0;
                    int read;
                    while ((read = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                    {
                        await fileStream.WriteAsync(buffer, 0, read);
                        totalRead += read;
                        if (totalBytes > 0)
                        {
                            var progress = (int)((totalRead * 100) / totalBytes);
                            fileModel.Progress = progress;
                            totalProgress.TotalReadKByte += (read / 1024);
                            DownloadPrograssChanged?.Invoke();
                        }
                    }
                }
            }
        }
        
    }
    DownloadCompleted?.Invoke();
  }
}

异步函数同步之后捕获不了异常

一定要加GetResult

webDataAccess.DownloadAsync(fi, localFileName, FileTotalProgress).GetAwaiter().GetResult();

相关推荐
光泽雨6 小时前
c#文件结构
c#
南無忘码至尊7 小时前
Unity学习90天-第2天-认识键盘 / 鼠标输入(PC)并实现WASD 移动,鼠标控制物体转向
学习·unity·c#·游戏开发
William_cl8 小时前
C# ASP.NET 分层架构实战:BLL (Service) 业务层从入门到封神(规范 + 避坑)
架构·c#·asp.net
qq_454245039 小时前
图数据标准化与智能去重框架:设计与实现解析
数据结构·架构·c#·图论
CSharp精选营9 小时前
C# 如何减少代码运行时间:7 个实战技巧
性能优化·c#·.net·技术干货·实战技巧
hhh3u3u3u1 天前
Visual C++ 6.0中文版安装包下载教程及win11安装教程
java·c语言·开发语言·c++·python·c#·vc-1
加号31 天前
【C#】实现沃德普线光控制器通信控制(附完整源码)
开发语言·c#
lzhdim1 天前
SharpCompress:跨平台的 C# 压缩与解压库
开发语言·c#
~plus~1 天前
.NET 8 C# 委托与事件实战教程
网络·c#·.net·.net 8·委托与事件·c#进阶
beyond谚语1 天前
接口&抽象类
c#·接口隔离原则·抽象类