You know the WeatherForecast code you get when you type dotnet new webapi? Well, this sample starts with that but also demonstrates a token-based polling pattern for long-running operations (LROs). Instead of forcing clients to wait for work to finish synchronously, the API accepts a request, immediately acknowledges it with 202 Accepted, and hands back an operation token that the caller can poll. You can easily replace the WeatherForecast code with your own long running code -- you may not need to change anything else!
Both the Microsoft REST API Guidelines and Google Cloud APIs recommend this approach for operations that may take seconds or minutes to complete.
POST /jobsrecords the work request and returns quickly.- The response carries a token (or operation URL) that uniquely identifies the job.
- Clients poll
/jobs/{id}at their preferred cadence. - The server reports status along the way:
202 Acceptedwhile processing is in progress.200 OK(or201 Created) with the final payload when the job completes.4xx/5xxif the job fails.
This design decouples client responsiveness from job duration, supports retries naturally, and keeps server resources free from long-held connections.
Controllers/JobsController.csorchestrates job submission, cancellation, and status checks.Services/IJobProcessor.csand implementations represent long-running work.Services/IJobStore.csencapsulates job persistence;InMemoryJobStoreandCachedJobStoreillustrate different storage approaches.Models/JobResult.csandModels/JobStatus.csdefine the data contracts returned by the API.
AppModels/WeatherForecastRequest.csandModels/WeatherForecastResponse.cscapture the polling job input and payload delivered on completion.AppServices/WeatherForecastJobProcessor.csis the long running process -- replace this with your code.
- .NET SDK 10.0 (preview) or later to match the target framework specified in
api.csproj. - PowerShell 7+ (optional) for the demo script in
scripts/demo-weather.ps1.
- Restore dependencies:
dotnet restore
- Run the API locally:
dotnet run --project api - The service listens on the URL defined in
Properties/launchSettings.json(by defaulthttps://localhost:7182).
To create a new project based on this template, run the following command:
dotnet new webapi-polling -o <myProject>-
Submit a job
POST /jobs Content-Type: application/json { "city": "Seattle", "date": "2025-11-08" }
Example response:
HTTP/1.1 202 Accepted Location: /jobs/7b57f728-7f66-4f7f-a788-4c9b6e0a6f1c Retry-After: 2 { "jobId": "7b57f728-7f66-4f7f-a788-4c9b6e0a6f1c", "status": "Pending" }
The
datefield is optional; when omitted the processor selects a default forecast date. -
Poll for status
GET /jobs/7b57f728-7f66-4f7f-a788-4c9b6e0a6f1c
Possible responses:
202 Acceptedwith a body containing the currentJobStatus.200 OKwith the finalJobResult, whosedataproperty holds aWeatherForecastResponsepayload:{ "jobId": "7b57f728-7f66-4f7f-a788-4c9b6e0a6f1c", "status": "Completed", "data": { "city": "Seattle", "date": "2025-11-08", "temperatureC": 11, "summary": "Totals decrease overnight" } }404 Not Foundif the token is unknown or has expired.
-
Handle completion or failure
- On success, persist or display the returned result.
- On failure, inspect the error payload and decide whether to retry the original submission.
| Method | Route | Description |
|---|---|---|
| POST | /jobs/weather |
Submit a new long-running job request. |
| POST | /jobs/lottery |
Submit a new long-running job request. |
| GET | /jobs/{id} |
Retrieve current status or final result. |
| DELETE | /jobs/{id} |
Cancel a job that is still in progress. |
| DELETE | /jobs/{id}?purge=true |
Cancel and Delete a job from the cache. |
Sample requests are captured in api.http, which can be executed with the VS Code REST Client extension or with tools such as curl/Invoke-WebRequest.
Run scripts/demo-weather.ps1 to see the polling pattern end-to-end. The script submits a weather forecast job, polls until completion, and prints the resulting forecast.
- Use the
demo-weather.mdplaybook to follow manual test steps. - Add integration tests that mimic the polling loop by verifying transitions from
Pending→Running→Completed/FailedinJobStatus.
- Microsoft REST API Guidelines (long-running operations section)
- Google Cloud API Design Guide (operation resources)
These documents inspired the token-based polling approach implemented here.