Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Deze handleiding begeleidt u bij het migreren van uw .NET Durable Functions-app van het in-procesmodel naar het geïsoleerde werkrolmodel. Het in-process model bereikt het einde van de ondersteuning op 10 november 2026. Na die datum worden er geen beveiligingsupdates of oplossingen voor fouten opgegeven. Het geïsoleerde werkrolmodel biedt u ook volledige procesbeheer, standaard .NET afhankelijkheidsinjectie en toegang tot de nieuwste platformfuncties.
Waarschuwing
De ondersteuning voor het in-process model eindigt op 10 november 2026. U wordt aangeraden nu te migreren. Zie
Controlelijst voor migratie
Gebruik de volgende controlelijst om de voortgang van elke migratiestap bij te houden:
| Stap | Afdeling |
|---|---|
| Vereisten verifiëren | Prerequisites |
| 2. Het projectbestand bijwerken | Het projectbestand bijwerken |
| 3. Program.cs toevoegen | Program.cs toevoegen |
| 4. Pakketverwijzingen bijwerken | Pakketverwijzingen bijwerken |
| 5. Functiecode bijwerken | Functiecode bijwerken |
| 6. local.settings.json bijwerken | local.settings.jsonbijwerken |
| 7. Lokaal testen | Lokaal testen |
| 8. Implementeren in Azure | Implementeren naar Azure |
Vereiste voorwaarden
- Azure Functions Core Tools v4.x of hoger
- .NET 8.0 SDK (of uw doelversie van .NET)
- Visual Studio 2022 of VS Code met Azure Functions extensie
Apps identificeren die moeten worden gemigreerd (optioneel)
Als u niet zeker weet welke apps het in-process model nog steeds gebruiken, voert u dit Azure PowerShell script uit:
$FunctionApps = Get-AzFunctionApp
$AppInfo = @{}
foreach ($App in $FunctionApps)
{
if ($App.Runtime -eq 'dotnet')
{
$AppInfo.Add($App.Name, $App.Runtime)
}
}
$AppInfo
Apps die als runtime worden weergegeven dotnet , maken gebruik van het in-process model. Apps die al dotnet-isolated gebruikmaken van het geïsoleerde werkrolmodel.
Het projectbestand bijwerken
Vóór (in behandeling)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.1" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.DurableTask" Version="2.13.0" />
</ItemGroup>
</Project>
Na (geïsoleerde werker)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.2" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.1" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.14.1" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext"/>
</ItemGroup>
</Project>
De belangrijkste wijzigingen zijn het overschakelen naar een uitvoerbaar uitvoertype en het vervangen van alle Microsoft.Azure.WebJobs.*-pakketten door hun Microsoft.Azure.Functions.Worker.* equivalenten.
Program.cs toevoegen
Voor het geïsoleerde werkrolmodel is een Program.cs toegangspunt vereist. Maak dit bestand in de hoofdmap van uw project. Als u een FunctionsStartup class in Startup.cs hebt, verplaatst u die serviceregistraties naar het ConfigureServices blok en verwijdert u Startup.cs.
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services => {
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
// Add your custom services here (previously in FunctionsStartup)
// services.AddSingleton<IMyService, MyService>();
})
.Build();
host.Run();
Pakketverwijzingen bijwerken
pakkettoewijzing Durable Functions
| Pakket in behandeling | Pakket voor geïsoleerde werknemer |
|---|---|
Microsoft.Azure.WebJobs.Extensions.DurableTask |
Microsoft.Azure.Functions.Worker.Extensions.DurableTask |
Microsoft.DurableTask.SqlServer.AzureFunctions |
Microsoft.Azure.Functions.Worker.Extensions.DurableTask.SqlServer |
Microsoft.Azure.DurableTask.Netherite.AzureFunctions |
Microsoft.Azure.Functions.Worker.Extensions.DurableTask.Netherite |
Algemene mapping van extensiepakketten
| In behandeling | Geïsoleerde werkrol |
|---|---|
Microsoft.Azure.WebJobs.Extensions.Storage |
Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs, .Queues, .Tables |
Microsoft.Azure.WebJobs.Extensions.CosmosDB |
Microsoft.Azure.Functions.Worker.Extensions.CosmosDB |
Microsoft.Azure.WebJobs.Extensions.ServiceBus |
Microsoft.Azure.Functions.Worker.Extensions.ServiceBus |
Microsoft.Azure.WebJobs.Extensions.EventHubs |
Microsoft.Azure.Functions.Worker.Extensions.EventHubs |
Microsoft.Azure.WebJobs.Extensions.EventGrid |
Microsoft.Azure.Functions.Worker.Extensions.EventGrid |
Belangrijk
Verwijder verwijzingen naar Microsoft.Azure.WebJobs.* naamruimten en Microsoft.Azure.Functions.Extensions uit uw project.
Functiecode bijwerken
In deze sectie worden de codewijzigingen voor elk Durable Functions type beschreven. Ga naar de sectie voor de functietypen die uw app gebruikt:
- Naamruimtewijzigingen
- Orchestrator functies
- Activiteitsfuncties
- Clientfuncties
- Beleid voor opnieuw proberen (indien gebruikt)
- Entiteitsfuncties (indien gebruikt)
Zie de API-verwijzing voor de volledige API-per-API-mapping.
Naamruimtewijzigingen
// Before (In-Process)
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
// After (Isolated Worker)
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.DurableTask;
using Microsoft.DurableTask.Client;
using Microsoft.DurableTask.Entities;
Wijzigingen in functiekenmerk
// Before (In-Process)
[FunctionName("MyOrchestrator")]
// After (Isolated Worker)
[Function(nameof(MyOrchestrator))]
Wijzigingen in orchestratorfunctie
Voordat (In-Process):
[FunctionName("OrderOrchestrator")]
public static async Task<OrderResult> RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context,
ILogger log)
{
var order = context.GetInput<Order>();
await context.CallActivityAsync("ValidateOrder", order);
await context.CallActivityAsync("ProcessPayment", order.Payment);
await context.CallActivityAsync("ShipOrder", order);
return new OrderResult { Success = true };
}
Na (geïsoleerde werker):
[Function(nameof(OrderOrchestrator))]
public static async Task<OrderResult> OrderOrchestrator(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
ILogger logger = context.CreateReplaySafeLogger(nameof(OrderOrchestrator));
var order = context.GetInput<Order>();
await context.CallActivityAsync("ValidateOrder", order);
await context.CallActivityAsync("ProcessPayment", order.Payment);
await context.CallActivityAsync("ShipOrder", order);
return new OrderResult { Success = true };
}
Belangrijkste verschillen
| Aspect | In behandeling | Geïsoleerde werknemer |
|---|---|---|
| Contexttype | IDurableOrchestrationContext |
TaskOrchestrationContext |
| Logger |
ILogger-parameter |
context.CreateReplaySafeLogger() |
| Attribute | [FunctionName] |
[Function] |
Wijzigingen in de activiteitsfunctie
Voordat (In-Process):
[FunctionName("ValidateOrder")]
public static bool ValidateOrder(
[ActivityTrigger] Order order,
ILogger log)
{
log.LogInformation("Validating order {OrderId}", order.Id);
return order.Items.Any() && order.TotalAmount > 0;
}
Na (geïsoleerde werker):
[Function(nameof(ValidateOrder))]
public static bool ValidateOrder(
[ActivityTrigger] Order order,
FunctionContext executionContext)
{
ILogger logger = executionContext.GetLogger(nameof(ValidateOrder));
logger.LogInformation("Validating order {OrderId}", order.Id);
return order.Items.Any() && order.TotalAmount > 0;
}
Wijzigingen in clientfuncties
Voordat (In-Process):
[FunctionName("StartOrder")]
public static async Task<IActionResult> StartOrder(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req,
[DurableClient] IDurableOrchestrationClient client,
ILogger log)
{
var order = await req.ReadFromJsonAsync<Order>();
string instanceId = await client.StartNewAsync("OrderOrchestrator", order);
return client.CreateCheckStatusResponse(req, instanceId);
}
Na (geïsoleerde werker):
[Function("StartOrder")]
public static async Task<HttpResponseData> StartOrder(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req,
[DurableClient] DurableTaskClient client,
FunctionContext executionContext)
{
ILogger logger = executionContext.GetLogger("StartOrder");
var order = await req.ReadFromJsonAsync<Order>();
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
nameof(OrderOrchestrator),
order
);
return await client.CreateCheckStatusResponseAsync(req, instanceId);
}
Wijzigingen in clienttype
| In behandeling | Geïsoleerde werkrol |
|---|---|
IDurableOrchestrationClient |
DurableTaskClient |
StartNewAsync() |
ScheduleNewOrchestrationInstanceAsync() |
CreateCheckStatusResponse() |
CreateCheckStatusResponseAsync() |
HttpRequest / IActionResult |
HttpRequestData / HttpResponseData |
Beleidswijzigingen opnieuw proberen
In-process gebruikt RetryOptions met CallActivityWithRetryAsync. De geïsoleerde werknemer gebruikt TaskOptions met de standaard CallActivityAsync.
Voordat (In-Process):
var retryOptions = new RetryOptions(
firstRetryInterval: TimeSpan.FromSeconds(5),
maxNumberOfAttempts: 3);
string result = await context.CallActivityWithRetryAsync<string>(
"MyActivity", retryOptions, input);
Na (geïsoleerde werker):
var retryOptions = new TaskOptions(
new TaskRetryOptions(new RetryPolicy(
maxNumberOfAttempts: 3,
firstRetryInterval: TimeSpan.FromSeconds(5))));
string result = await context.CallActivityAsync<string>(
"MyActivity", input, retryOptions);
Wijzigingen in entiteitsfuncties
Voordat (In-Process):
[FunctionName(nameof(Counter))]
public static void Counter([EntityTrigger] IDurableEntityContext ctx)
{
switch (ctx.OperationName.ToLowerInvariant())
{
case "add":
ctx.SetState(ctx.GetState<int>() + ctx.GetInput<int>());
break;
case "get":
ctx.Return(ctx.GetState<int>());
break;
}
}
Na (geïsoleerde werker):
[Function(nameof(Counter))]
public static Task Counter([EntityTrigger] TaskEntityDispatcher dispatcher)
{
return dispatcher.DispatchAsync<CounterEntity>();
}
public class CounterEntity
{
public int Value { get; set; }
public void Add(int amount) => Value += amount;
public int Get() => Value;
}
Wijzigingen in foutengedrag
Bekijk deze wijzigingen voordat u de gemigreerde app test. Zie de API-referentie voor de volledige API-voor-API-overzicht.
Waarschuwing
Standaard serialisatie is gewijzigd: de geïsoleerde worker gebruikt standaard System.Text.Json in plaats van Newtonsoft.Json. Als uw orkestraties complexe objecten doorgeven, test de serialisatie zorgvuldig. Zie de verschillen in JSON-serialisatie voor configuratieopties.
Waarschuwing
ContinueAsNew-standaardwijziging: de standaardwaarde van de preserveUnprocessedEvents parameter is gewijzigd van false (2.x) in true (geïsoleerd). Als uw orkestratie gebruikmaakt van ContinueAsNew en afhankelijk is van niet-verwerkte gebeurtenissen die worden verwijderd, moet u expliciet preserveUnprocessedEvents: false doorgeven.
Opmerking
Standaardwijziging restartAsync: de standaardwaarde van de restartWithNewInstanceId parameter is gewijzigd van true (2.x) in false (geïsoleerd). Als uw code aanroept RestartAsync en afhankelijk is van een nieuwe exemplaar-id die wordt gegenereerd, geeft u expliciet door restartWithNewInstanceId: true.
Andere belangrijke wijzigingen:
-
Entiteitsproxy's die zijn verwijderd ,
CreateEntityProxy<T>zijn niet beschikbaar. GebruikEntities.CallEntityAsyncofEntities.SignalEntityAsyncrechtstreeks. -
Cross-task-hub-bewerkingen verwijderd — Overbelastingen die
taskHubName/connectionNameaccepteerden zijn niet beschikbaar. Alleen bewerkingen met dezelfde taakhub worden ondersteund. -
Orchestratiegeschiedenis verplaatst -
DurableOrchestrationStatus.Historybevindt zich niet meer op het statusobject. GebruikDurableTaskClient.GetOrchestrationHistoryAsync.
local.settings.jsonbijwerken
De belangrijkste wijziging is het instellen van FUNCTIONS_WORKER_RUNTIME van dotnet naar dotnet-isolated:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
}
}
Opmerking
De back-endconfiguratie van uw opslag (Azure Storage, MSSQL, Netherite of Durable Task Scheduler) wordt niet gewijzigd door de migratie. Bewaar uw bestaande opslaginstellingen.
Lokaal testen
Voer uw functie-app lokaal uit en controleer of alle indelingen, activiteiten en entiteiten correct werken.
func start
Functionaliteit controleren
Test de volgende scenario's indien van toepassing:
- Start een orchestratie met een HTTP-trigger
- De orkestratiestatus bewaken
- De uitvoeringsvolgorde van de activiteit controleren
- Entiteitsbewerkingen testen indien van toepassing
- Application Insights-telemetrie controleren
Implementeren in Azure
Aanbevolen: Implementatieslots gebruiken
Implementatiesites gebruiken om downtime te minimaliseren:
- Maak een staging-slot voor uw functie-app.
-
Configuratie van staging-site bijwerken:
- Stel
FUNCTIONS_WORKER_RUNTIMEin opdotnet-isolated. - Werk indien nodig .NET stackversie bij.
- Stel
- Gemigreerde code implementeren in de staging-slot.
- Test grondig in de staging-slot.
- Voer sleuvenwissel uit om wijzigingen naar productie te verplaatsen.
Toepassingsinstellingen bijwerken
In de Azure-portal of via CLI:
az functionapp config appsettings set \
--name <FUNCTION_APP_NAME> \
--resource-group <RESOURCE_GROUP> \
--settings FUNCTIONS_WORKER_RUNTIME=dotnet-isolated
Stackconfiguratie bijwerken
Als u een andere .NET versie wilt gebruiken:
az functionapp config set \
--name <FUNCTION_APP_NAME> \
--resource-group <RESOURCE_GROUP> \
--net-framework-version v8.0
Veelvoorkomende migratieproblemen
Probleem: fouten bij het laden van assemblages
Symptoom:Could not load file or assembly Fouten.
Solution: Zorg ervoor dat u alle Microsoft.Azure.WebJobs.* pakketverwijzingen verwijdert en vervangt door geïsoleerde werkrolequivalenten.
Probleem: bindingskenmerk niet gevonden
Symptoom:The type or namespace 'QueueTrigger' could not be found
Oplossing: Voeg het juiste extensiepakket toe en werk bij met behulp van instructies:
// Add using statement
using Microsoft.Azure.Functions.Worker;
// Install package
// dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues
Probleem: IDurableOrchestrationContext niet gevonden
Symptoom:The type or namespace 'IDurableOrchestrationContext' could not be found
Oplossing: Vervangen door TaskOrchestrationContext:
using Microsoft.DurableTask;
[Function(nameof(MyOrchestrator))]
public static async Task MyOrchestrator([OrchestrationTrigger] TaskOrchestrationContext context)
{
// ...
}
Probleem: verschillen in JSON-serialisatie
Symptoom: Serialisatiefouten of onverwachte gegevensindelingen
Oplossing: Het geïsoleerde model gebruikt System.Text.Json standaard. Serialisatie configureren in Program.cs:
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services => {
services.Configure<JsonSerializerOptions>(options => {
options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});
})
.Build();
Gebruik in plaats daarvan Newtonsoft.Json:
services.Configure<WorkerOptions>(options => {
options.Serializer = new NewtonsoftJsonObjectSerializer();
});
Probleem: Aangepaste serialisatie-instellingen migreren
Symptoom: U hebt IMessageSerializerSettingsFactory in het in-procesmodel gebruikt en hebt het equivalent in een geïsoleerde werker nodig.
Oplossing: Configureer de serialisatiefunctie op werkniveau in Program.cs. Zie de sectie behaviorale wijzigingen van de API-verwijzing en Serialisatie en persistentie in Durable Functions voor meer informatie.
Newtonsoft.Json gebruiken met aangepaste instellingen:
// Program.cs
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.Configure<WorkerOptions>(options =>
{
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.None,
DateFormatHandling = DateFormatHandling.IsoDateFormat,
};
options.Serializer = new NewtonsoftJsonObjectSerializer(settings);
});
})
.Build();
Opmerking
Deze aanpak vereist de Newtonsoft.Json en Azure.Core.Serialization NuGet-pakketten.
Checklist
Gebruik deze controlelijst om een volledige migratie te garanderen:
- Projectbestand bijgewerkt met
<OutputType>Exe</OutputType> -
Microsoft.NET.Sdk.Functionsvervangen door werkpakketten - Vervangen
Microsoft.Azure.WebJobs.Extensions.DurableTaskdoor geïsoleerd pakket - Gemaakt
Program.csmet hostconfiguratie - Klasse verwijderd
FunctionsStartup(indien aanwezig) - Alles
[FunctionName]bijgewerkt naar[Function] -
IDurableOrchestrationContextVervangen doorTaskOrchestrationContext -
IDurableOrchestrationClientVervangen doorDurableTaskClient - Logboekregistratie bijgewerkt voor gebruik van DI of
FunctionContext - Bijgewerkt
local.settings.jsonmetdotnet-isolatedruntime-omgeving - Alle
Microsoft.Azure.WebJobs.*met behulp van instructies verwijderd -
Microsoft.Azure.Functions.Workermet behulp van instructies toegevoegd -
CreateEntityProxy<T>Vervangen door directeCallEntityAsync/SignalEntityAsyncaanroepen - Vervangen van overbelastingen bij huboperaties met meerdere taken (indien gebruikt)
- Batch
GetStatusAsync/PurgeInstanceHistoryAsync-by-ID-aanroepen vervangen door op filters gebaseerde of afzonderlijke aanroepen - Gemigreerde
DurableOrchestrationStatus.Historytoegang totGetOrchestrationHistoryAsync - Parameters voor entiteitsconstructor
DispatchAsyncbijgewerkt voor het gebruik van DI - Alle functies lokaal getest
- Geïmplementeerd in staging-site en geverifieerd
- Gewisseld naar productieomgeving
Volgende stappen
- In-process to isolated worker API mapping — complete API reference for your migration (In-process to isolated worker API mapping) - volledige API-verwijzing voor uw migratie
- overzicht van Durable Functions voor .NET geïsoleerde werkrol
- Durable Functions versies en migratiehandleiding