Skip to content

Commit

Permalink
Upgrade TFMs to .NET 8.0, and packages (#38752)
Browse files Browse the repository at this point in the history
* Upgrade TFMs to .NET 8.0, and packages

* Remove worker versioning

* Fix ranges, etc.
  • Loading branch information
IEvangelist authored Dec 15, 2023
1 parent 7fc625a commit 114b8f9
Show file tree
Hide file tree
Showing 218 changed files with 481 additions and 3,068 deletions.
6 changes: 3 additions & 3 deletions docs/core/extensions/cloud-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Deploy a Worker Service to Azure
description: Deploy your .NET Worker Service to Azure with ease, learning from a step-by-step process to optimize your workflow, including Docker and Azure Container Registry.
author: IEvangelist
ms.author: dapine
ms.date: 08/18/2023
ms.date: 12/13/2023
ms.topic: tutorial
zone_pivot_groups: development-environment-one
---
Expand Down Expand Up @@ -66,14 +66,14 @@ With the CLI, the *Dockerfile* is **not** created for you. Copy its contents int

:::zone-end

:::code language="dockerfile" source="snippets/workers/7.0/cloud-service/Dockerfile":::
:::code language="dockerfile" source="snippets/workers/cloud-service/Dockerfile":::

:::zone target="docs" pivot="cli"

> [!NOTE]
> You need to update the various lines in the *Dockerfile* that reference *App.CloudService—replace this with the name of your project.
For more information on the official .NET images, see [Docker Hub: .NET Runtime](https://hub.docker.com/_/microsoft-dotnet-runtime?tab=description) and [Docker Hub: .NET SDK](https://hub.docker.com/_/microsoft-dotnet-sdk?tab=description).
For more information on the official .NET images, see [Docker Hub: .NET Runtime](https://hub.docker.com/_/microsoft-dotnet-runtime) and [Docker Hub: .NET SDK](https://hub.docker.com/_/microsoft-dotnet-sdk).

:::zone-end

Expand Down
Binary file removed docs/core/extensions/media/profile-settings-6.0.png
Binary file not shown.
Binary file removed docs/core/extensions/media/profile-settings-7.0.png
Binary file not shown.
Binary file added docs/core/extensions/media/profile-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
81 changes: 8 additions & 73 deletions docs/core/extensions/queue-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ title: Create a Queue Service
description: Learn how to create a queue service subclass of BackgroundService in .NET.
author: IEvangelist
ms.author: dapine
ms.date: 05/12/2023
ms.date: 12/13/2023
ms.topic: tutorial
zone_pivot_groups: dotnet-version
---

# Create a Queue Service
Expand All @@ -24,21 +23,10 @@ In this tutorial, you learn how to:

## Prerequisites

:::zone target="docs" pivot="dotnet-8-0,dotnet-7-0"

- The [.NET 7.0 SDK or later](https://dotnet.microsoft.com/download/dotnet/7.0)
- A .NET integrated development environment (IDE)
- Feel free to use [Visual Studio](https://visualstudio.microsoft.com)

:::zone-end
:::zone target="docs" pivot="dotnet-6-0"

- The [.NET 6.0 SDK or later](https://dotnet.microsoft.com/download/dotnet/6.0)
- The [.NET 8.0 SDK or later](https://dotnet.microsoft.com/download/dotnet/8.0)
- A .NET integrated development environment (IDE)
- Feel free to use [Visual Studio](https://visualstudio.microsoft.com)

:::zone-end

<!-- ## Create a new project -->
[!INCLUDE [file-new-worker](includes/file-new-worker.md)]

Expand All @@ -51,29 +39,11 @@ You may be familiar with the <xref:System.Web.Hosting.HostingEnvironment.QueueBa
In .NET, to model a service that is inspired by the `QueueBackgroundWorkItem` functionality, start by adding an `IBackgroundTaskQueue` interface to the project:

:::zone target="docs" pivot="dotnet-8-0,dotnet-7-0"

:::code source="snippets/workers/7.0/queue-service/IBackgroundTaskQueue.cs":::

:::zone-end
:::zone target="docs" pivot="dotnet-6-0"

:::code source="snippets/workers/6.0/queue-service/IBackgroundTaskQueue.cs":::

:::zone-end
:::code source="snippets/workers/queue-service/IBackgroundTaskQueue.cs":::

There are two methods, one that exposes queuing functionality, and another that dequeues previously queued work items. A *work item* is a `Func<CancellationToken, ValueTask>`. Next, add the default implementation to the project.

:::zone target="docs" pivot="dotnet-8-0,dotnet-7-0"

:::code source="snippets/workers/7.0/queue-service/DefaultBackgroundTaskQueue.cs":::

:::zone-end
:::zone target="docs" pivot="dotnet-6-0"

:::code source="snippets/workers/6.0/queue-service/DefaultBackgroundTaskQueue.cs":::

:::zone-end
:::code source="snippets/workers/queue-service/DefaultBackgroundTaskQueue.cs":::

The preceding implementation relies on a <xref:System.Threading.Channels.Channel%601> as a queue. The <xref:System.Threading.Channels.BoundedChannelOptions.%23ctor(System.Int32)> is called with an explicit capacity. Capacity should be set based on the expected application load and number of concurrent threads accessing the queue. <xref:System.Threading.Channels.BoundedChannelFullMode.Wait?displayProperty=nameWithType> causes calls to <xref:System.Threading.Channels.ChannelWriter%601.WriteAsync%2A?displayProperty=nameWithType> to return a task, which completes only when space becomes available. Which leads to backpressure, in case too many publishers/calls start accumulating.

Expand All @@ -87,16 +57,7 @@ In the following `QueueHostedService` example:

Replace the existing `Worker` class with the following C# code, and rename the file to *QueueHostedService.cs*.

:::zone target="docs" pivot="dotnet-8-0,dotnet-7-0"

:::code source="snippets/workers/7.0/queue-service/QueuedHostedService.cs" highlight="29-30,32":::

:::zone-end
:::zone target="docs" pivot="dotnet-6-0"

:::code source="snippets/workers/6.0/queue-service/QueuedHostedService.cs" highlight="29-30,32":::

:::zone-end
:::code source="snippets/workers/queue-service/QueuedHostedService.cs" highlight="25-26,28":::

A `MonitorLoop` service handles enqueuing tasks for the hosted service whenever the `w` key is selected on an input device:

Expand All @@ -106,41 +67,15 @@ A `MonitorLoop` service handles enqueuing tasks for the hosted service whenever
- Three 5-second delays are executed <xref:System.Threading.Tasks.Task.Delay%2A>.
- A `try-catch` statement traps <xref:System.OperationCanceledException> if the task is canceled.

:::zone target="docs" pivot="dotnet-8-0,dotnet-7-0"

:::code source="snippets/workers/7.0/queue-service/MonitorLoop.cs" highlight="5,10,35":::
:::zone-end
:::zone target="docs" pivot="dotnet-6-0"

:::code source="snippets/workers/6.0/queue-service/MonitorLoop.cs" highlight="5,10,35":::

:::zone-end
:::code source="snippets/workers/queue-service/MonitorLoop.cs" highlight="4,26":::

Replace the existing `Program` contents with the following C# code:

:::zone target="docs" pivot="dotnet-8-0,dotnet-7-0"

:::code source="snippets/workers/7.0/queue-service/Program.cs" highlight="4-14":::

:::zone-end
:::zone target="docs" pivot="dotnet-6-0"

:::code source="snippets/workers/6.0/queue-service/Program.cs" highlight="3-18":::

:::zone-end
:::code source="snippets/workers/queue-service/Program.cs" highlight="4-14":::

The services are registered in (*Program.cs*). The hosted service is registered with the `AddHostedService` extension method. `MonitorLoop` is started in *Program.cs* top-level statement:

:::zone target="docs" pivot="dotnet-8-0,dotnet-7-0"

:::code source="snippets/workers/7.0/queue-service/Program.cs" range="18-19":::

:::zone-end
:::zone target="docs" pivot="dotnet-6-0"

:::code source="snippets/workers/6.0/queue-service/Program.cs" range="22-23":::

:::zone-end
:::code source="snippets/workers/queue-service/Program.cs" range="18-19":::

For more information on registering services, see [Dependency injection in .NET](dependency-injection.md).

Expand Down
60 changes: 6 additions & 54 deletions docs/core/extensions/scoped-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ title: Use scoped services within a BackgroundService
description: Learn how to use scoped services within a BackgroundService in .NET.
author: IEvangelist
ms.author: dapine
ms.date: 03/13/2023
ms.date: 12/13/2023
ms.topic: tutorial
zone_pivot_groups: dotnet-version
---

# Use scoped services within a `BackgroundService`
Expand All @@ -24,86 +23,39 @@ In this tutorial, you learn how to:

## Prerequisites

:::zone target="docs" pivot="dotnet-8-0,dotnet-7-0"

- The [.NET 7.0 SDK or later](https://dotnet.microsoft.com/download/dotnet/7.0)
- A .NET integrated development environment (IDE)
- Feel free to use [Visual Studio](https://visualstudio.microsoft.com)

:::zone-end
:::zone target="docs" pivot="dotnet-6-0"

- The [.NET 6.0 SDK or later](https://dotnet.microsoft.com/download/dotnet/6.0)
- The [.NET 8.0 SDK or later](https://dotnet.microsoft.com/download/dotnet/8.0)
- A .NET integrated development environment (IDE)
- Feel free to use [Visual Studio](https://visualstudio.microsoft.com)

:::zone-end

<!-- ## Create a new project -->
[!INCLUDE [file-new-worker](includes/file-new-worker.md)]

## Create scoped services

To use [scoped services](dependency-injection.md#scoped) within a `BackgroundService`, create a scope. No scope is created for a hosted service by default. The scoped background service contains the background task's logic.

:::zone target="docs" pivot="dotnet-8-0,dotnet-7-0"

:::code source="snippets/workers/7.0/scoped-service/IScopedProcessingService.cs":::

:::zone-end
:::zone target="docs" pivot="dotnet-6-0"

:::code source="snippets/workers/6.0/scoped-service/IScopedProcessingService.cs":::

:::zone-end
:::code source="snippets/workers/scoped-service/IScopedProcessingService.cs":::

The preceding interface defines a single `DoWorkAsync` method. To define the default implementation:

- The service is asynchronous. The `DoWorkAsync` method returns a `Task`. For demonstration purposes, a delay of ten seconds is awaited in the `DoWorkAsync` method.
- An <xref:Microsoft.Extensions.Logging.ILogger> is injected into the service.:

:::zone target="docs" pivot="dotnet-8-0,dotnet-7-0"

:::code source="snippets/workers/7.0/scoped-service/DefaultScopedProcessingService.cs":::

:::zone-end
:::zone target="docs" pivot="dotnet-6-0"

:::code source="snippets/workers/6.0/scoped-service/DefaultScopedProcessingService.cs":::

:::zone-end
:::code source="snippets/workers/scoped-service/DefaultScopedProcessingService.cs":::

The hosted service creates a scope to resolve the scoped background service to call its `DoWorkAsync` method. `DoWorkAsync` returns a `Task`, which is awaited in `ExecuteAsync`:

## Rewrite the Worker class

Replace the existing `Worker` class with the following C# code, and rename the file to *ScopedBackgroundService.cs*:

:::zone target="docs" pivot="dotnet-8-0,dotnet-7-0"

:::code source="snippets/workers/7.0/scoped-service/ScopedBackgroundService.cs" highlight="26-32":::

:::zone-end
:::zone target="docs" pivot="dotnet-6-0"

:::code source="snippets/workers/6.0/scoped-service/ScopedBackgroundService.cs" highlight="26-32":::

:::zone-end
:::code source="snippets/workers/scoped-service/ScopedBackgroundService.cs" highlight="22-28":::

In the preceding code, an explicit scope is created and the `IScopedProcessingService` implementation is resolved from the dependency injection service provider. The resolved service instance is scoped, and its `DoWorkAsync` method is awaited.

Replace the template *Program.cs* file contents with the following C# code:

:::zone target="docs" pivot="dotnet-8-0,dotnet-7-0"

:::code source="snippets/workers/7.0/scoped-service/Program.cs" highlight="4-5":::

:::zone-end
:::zone target="docs" pivot="dotnet-6-0"

:::code source="snippets/workers/6.0/scoped-service/Program.cs" highlight="4-8":::

:::zone-end
:::code source="snippets/workers/scoped-service/Program.cs" highlight="4-5":::

The services are registered in (*Program.cs*). The hosted service is registered with the `AddHostedService` extension method.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<RootNamespace>CachingExamples.DistributedApis</RootNamespace>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<RootNamespace>CachingExamples.MemoryApis</RootNamespace>
Expand All @@ -10,7 +10,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup>

</Project>
35 changes: 14 additions & 21 deletions docs/core/extensions/snippets/caching/memory-worker/CacheWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,75 +3,68 @@

namespace CachingExamples.Memory;

public sealed class CacheWorker : BackgroundService
public sealed class CacheWorker(
ILogger<CacheWorker> logger,
HttpClient httpClient,
CacheSignal<Photo> cacheSignal,
IMemoryCache cache) : BackgroundService
{
private readonly ILogger<CacheWorker> _logger;
private readonly HttpClient _httpClient;
private readonly CacheSignal<Photo> _cacheSignal;
private readonly IMemoryCache _cache;
private readonly TimeSpan _updateInterval = TimeSpan.FromHours(3);

private bool _isCacheInitialized = false;

private const string Url = "https://jsonplaceholder.typicode.com/photos";

public CacheWorker(
ILogger<CacheWorker> logger,
HttpClient httpClient,
CacheSignal<Photo> cacheSignal,
IMemoryCache cache) =>
(_logger, _httpClient, _cacheSignal, _cache) = (logger, httpClient, cacheSignal, cache);

public override async Task StartAsync(CancellationToken cancellationToken)
{
await _cacheSignal.WaitAsync();
await cacheSignal.WaitAsync();
await base.StartAsync(cancellationToken);
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Updating cache.");
logger.LogInformation("Updating cache.");

try
{
Photo[]? photos =
await _httpClient.GetFromJsonAsync<Photo[]>(
await httpClient.GetFromJsonAsync<Photo[]>(
Url, stoppingToken);

if (photos is { Length: > 0 })
{
_cache.Set("Photos", photos);
_logger.LogInformation(
cache.Set("Photos", photos);
logger.LogInformation(
"Cache updated with {Count:#,#} photos.", photos.Length);
}
else
{
_logger.LogWarning(
logger.LogWarning(
"Unable to fetch photos to update cache.");
}
}
finally
{
if (!_isCacheInitialized)
{
_cacheSignal.Release();
cacheSignal.Release();
_isCacheInitialized = true;
}
}

try
{
_logger.LogInformation(
logger.LogInformation(
"Will attempt to update the cache in {Hours} hours from now.",
_updateInterval.Hours);

await Task.Delay(_updateInterval, stoppingToken);
}
catch (OperationCanceledException)
{
_logger.LogWarning("Cancellation acknowledged: shutting down.");
logger.LogWarning("Cancellation acknowledged: shutting down.");
break;
}
}
Expand Down
Loading

0 comments on commit 114b8f9

Please sign in to comment.