{"id":24534563,"url":"https://github.com/bloomtom/httpprogress","last_synced_at":"2025-04-14T21:51:06.046Z","repository":{"id":65413990,"uuid":"158986345","full_name":"bloomtom/HttpProgress","owner":"bloomtom","description":"A set of extension methods for HttpClient which adds progress reporting.","archived":false,"fork":false,"pushed_at":"2020-01-29T03:10:32.000Z","size":38,"stargazers_count":17,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-13T22:08:43.169Z","etag":null,"topics":["httpclient","progress","stream"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bloomtom.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-25T00:57:42.000Z","updated_at":"2024-05-08T06:08:25.000Z","dependencies_parsed_at":"2023-01-23T10:55:06.012Z","dependency_job_id":null,"html_url":"https://github.com/bloomtom/HttpProgress","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bloomtom%2FHttpProgress","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bloomtom%2FHttpProgress/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bloomtom%2FHttpProgress/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bloomtom%2FHttpProgress/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bloomtom","download_url":"https://codeload.github.com/bloomtom/HttpProgress/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248968741,"owners_count":21191158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["httpclient","progress","stream"],"created_at":"2025-01-22T11:17:41.483Z","updated_at":"2025-04-14T21:51:06.026Z","avatar_url":"https://github.com/bloomtom.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HttpProgress\n\u003eA set of extension methods for `HttpClient` which adds progress reporting.\n\nHttpClient doesn't natively support progress reporting? Yes, it's true. You're expected to make your own `HttpContent` which overrides `SerializeToStreamAsync` for `PutAsync` and `PostAsync`, and you're expected to extend `GetAsync` with progress reporting in the stream copy logic. Well guess what? I've done that for you. \n\n## Nuget Packages\n\nPackage Name | Target Framework | Version\n---|---|---\n[HttpProgress](https://www.nuget.org/packages/bloomtom.HttpProgress) | .NET Standard 2.0 | ![NuGet](https://img.shields.io/nuget/v/bloomtom.HttpProgress.svg)\n\n\n## Usage\nAdd HttpProgress to your usings.\n```csharp\nusing HttpProgress;\n```\nUse the `HttpClient` extensions.\n```csharp\n// Make your progress event.\nvar progress = new Progress\u003cICopyProgress\u003e(x =\u003e // Please see \"Notes on IProgress\u003cT\u003e\"\n{\n    // This is your progress event!\n    // It will fire on every buffer fill so don't do anything expensive.\n    // Writing to the console IS expensive, so don't do the following in practice...\n    Console.WriteLine(x.PercentComplete.ToString(\"P\"));\n});\n\n// Post\nusing (var fileStream = System.IO.File.OpenRead(\"MyFile.txt\"))\n{\n    var result = await client.PostAsync(\"https://mysite.com/something\", fileStream, progress);\n}\n\n// Get\nusing (var downloadStream = new MemoryStream())\n{\n    var response = await client.GetAsync(\"https://mysite.com/something\", downloadStream, progress);\n}\n```\nWoah, that was easy. But what if you want more than just percent complete? Well the progress event actually gives you all of the following in `ICopyProgress`:\n```csharp\npublic interface ICopyProgress\n{\n\t/// \u003csummary\u003e\n\t/// The instantaneous data transfer rate.\n\t/// \u003c/summary\u003e\n\tint BytesPerSecond { get; }\n\t/// \u003csummary\u003e\n\t/// The total number of bytes transferred so far.\n\t/// \u003c/summary\u003e\n\tlong BytesTransferred { get; }\n\t/// \u003csummary\u003e\n\t/// The total number of bytes expected to be copied.\n\t/// \u003c/summary\u003e\n\tlong ExpectedBytes { get; }\n\t/// \u003csummary\u003e\n\t/// The percentage complete as a value 0-1.\n\t/// \u003c/summary\u003e\n\tdouble PercentComplete { get; }\n\t/// \u003csummary\u003e\n\t/// The total time elapsed so far.\n\t/// \u003c/summary\u003e\n\tTimeSpan TransferTime { get; }\n}\n```\n\n## Notes on `IProgress\u003cT\u003e`\n\n#### Concrete Implementation\n\nThe type [`Progress\u003cT\u003e`](https://docs.microsoft.com/en-us/dotnet/api/system.progress-1) is provided by the framework for use cases where the progress changed event should be processed through your application's synchronization context. This is useful for desktop UI applications where modifying controls from the progress event needs to be done on the event loop thread. For console applications, which have no intelligent synchronization context, the event will end up on the thread pool and _will likely be executed out of order_. If this is undesirable, consider using [`NaiveProgress\u003cT\u003e`](https://github.com/bloomtom/NaiveProgress) instead.\n\n#### Performance Considerations\n\nThe action you give for progress reporting will fire on every buffer cycle. This can happen _many_ times! With a 16kB buffer transfering a 10MB file will cause 640 events to be fired.\n\nIf you need to do time consuming operations, consider rate limiting them. A simple way to do this is to only fire your expensive operation when `TransferTime` or `PercentComplete` crosses specific thresholds. A more complex but \"prettier\" solution is to buffer `ICopyProgress` and have a threaded reader to refresh your UI on a timer.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbloomtom%2Fhttpprogress","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbloomtom%2Fhttpprogress","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbloomtom%2Fhttpprogress/lists"}