C# SignalR IProgress<int>

使用Progress<T>和Action<T>实现远程进度更新
本文档展示了一个服务器端如何通过实现IProgress<int>接口的Progress<int>类,结合Action<T>委托来在执行长时间任务时向客户端报告进度。在服务器端的ALongTimeTask方法中,通过传递一个Action委托到DoLongRunningThing方法,每当进度改变时,就会调用客户端的progressChanged事件,从而实现实时更新进度。客户端则监听progressChanged事件并显示当前进度。

实现IProgress<in T>接口的Progress<int T>类,接收一个Action<T>,通过这个委托显示进度。

服务器端:

  public async Task<string> ALongTimeTask()
        {
            //方法1
            //var p = new Progress<int>();
            //p.ProgressChanged += (a,count) =>
            //{
            //    Clients.Caller.progressChanged(count);
            //};
            // var ret = await DoLongRunningThing(p);
            //方法2
            var progress = new Progress<int>(percent => Clients.Caller.progressChanged(percent));
            var ret = await DoLongRunningThing(progress);
            return ret;
        }

        public async Task<string> DoLongRunningThing(IProgress<int> progress)
        {
            for (int i = 0; i <= 100; i += 5)
            {
                await Task.Delay(200);
                progress.Report(i);
            }
            return "Job complete!";
        }

客户端:


            ChatHubProxy.On("progressChanged", (count) =>
            {
                //display current count;
                WriteInfo("Percent: " + count);
            });

ChatHubProxy.Invoke("ALongTimeTask");

public async Task DownloadAllAsync( Dictionary<string, string> urls, IProgress<long> progress) { long downloadedSize = 0; var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); var options = new ParallelOptions { MaxDegreeOfParallelism = 8 }; await Parallel.ForEachAsync(urls, options, async (urlPair, ct) => { var tempPath = Path.GetTempFileName(); try { using var response = await httpClient.GetAsync(urlPair.Value, HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); using var stream = await response.Content.ReadAsStreamAsync(); using var fileStream = new FileStream(tempPath, FileMode.Create); var buffer = ArrayPool<byte>.Shared.Rent(65536); try { int bytesRead; while ((bytesRead = await stream.ReadAsync(buffer, ct)) > 0) { await fileStream.WriteAsync(buffer.AsMemory(0, bytesRead), ct); Interlocked.Add(ref downloadedSize, bytesRead); progress?.Report((downloadedSize)); } File.Move(tempPath, Path.Combine(FileSystem.AppDataDirectory, urlPair.Key), true); } finally { ArrayPool<byte>.Shared.Return(buffer); } } catch { // 错误处理 } finally { if (File.Exists(tempPath)) File.Delete(tempPath); } }); progress?.Report((downloadedSize)); // 最终报告 }这是一个已经可以实现下载的方法,现在需要在这个下载方法的基础上增加取消下载,暂停下载,断网续传方法,从viewmodel进行调用,需要实时返回已下载大小,前端需要实时进行进度计算
09-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值