Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez az útmutató végigvezeti a .NET Durable Functions alkalmazás migrálásán a folyamatban lévő modellről az izolált feldolgozói modellre. A folyamatban lévő modell 2026. november 10-én véget ér a támogatásnak. Ezt követően a rendszer nem biztosít biztonsági frissítéseket vagy hibajavításokat. Az izolált feldolgozói modell teljes folyamatvezérlést, standard .NET függőséginjektálást és hozzáférést biztosít a legújabb platformfunkciókhoz.
Warning
A folyamatban lévő modell támogatása 2026. november 10-én megszűnik. Javasoljuk a migrálást. Az izolált feldolgozói modell hátteréről lásd: .NET izolált feldolgozói folyamat áttekintése.
Migrálási ellenőrzőlista
Az alábbi ellenőrzőlistával nyomon követheti az egyes migrálási lépések előrehaladását:
| Lépés | Szakasz |
|---|---|
| 1. Az előfeltételek ellenőrzése | Prerequisites |
| 2. A projektfájl frissítése | A projektfájl frissítése |
| 3. Program.cs hozzáadása | Program.cs hozzáadása |
| 4. Csomaghivatkozások frissítése | Csomaghivatkozások frissítése |
| 5. Függvénykód frissítése | Függvénykód frissítése |
| 6. local.settings.json frissítése | local.settings.jsonfrissítése |
| 7. Helyi tesztelés | Helyi tesztelés |
| 8. Üzembe helyezés az Azure-ba | Üzembe helyezés az Azure-ban |
Prerequisites
- Azure Functions Core Tools v4.x vagy újabb
- .NET 8.0 SDK (vagy a cél .NET verziója)
- Visual Studio 2022 vagy VS-kód Azure Functions kiterjesztéssel
A migrálni kívánt alkalmazások azonosítása (nem kötelező)
Ha nem biztos abban, hogy mely alkalmazások használják továbbra is a folyamatban lévő modellt, futtassa ezt a Azure PowerShell szkriptet:
$FunctionApps = Get-AzFunctionApp
$AppInfo = @{}
foreach ($App in $FunctionApps)
{
if ($App.Runtime -eq 'dotnet')
{
$AppInfo.Add($App.Name, $App.Runtime)
}
}
$AppInfo
A futtatókörnyezetként megjelenített dotnet alkalmazások a folyamatban lévő modellt használják. Azok az alkalmazások, amelyek dotnet-isolated megjelenítik, már használják az izolált feldolgozói modellt.
A projektfájl frissítése
Előtte (folyamatban)
<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>
After (izolált munkaegység)
<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>
A fő változások a végrehajtható kimeneti típusra való váltás, és az összes Microsoft.Azure.WebJobs.* csomag lecserélése a Microsoft.Azure.Functions.Worker.*-ekvivalensekre.
Program.cs hozzáadása
Az izolált dolgozói modellhez belépési pont szükséges Program.cs. Hozza létre ezt a fájlt a projekt gyökérkönyvtárában. Ha van egy FunctionsStartup osztálya a Startup.cs-ban/-ben, helyezze át ezeket a szolgáltatásregisztrációkat a ConfigureServices blokkba, és törölje a Startup.cs elemet.
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();
Csomaghivatkozások frissítése
Durable Functions csomagleképezés
| Folyamatban lévő csomag | Izolált munkavállalói csomag |
|---|---|
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 |
A bővítménycsomagok gyakori hozzárendelése
| Folyamatban | Izolált munkavégző |
|---|---|
Microsoft.Azure.WebJobs.Extensions.Storage |
\ |
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 |
Important
Távolítsa el a Microsoft.Azure.WebJobs.* névterekre és Microsoft.Azure.Functions.Extensions mutató hivatkozásokat a projektből.
Függvénykód frissítése
Ez a szakasz az egyes Durable Functions-típusok kódmódosítását ismerteti. Ugorjon az alkalmazás által használt függvénytípusok szakaszára:
- Névtérváltozások
- Orchestráló függvények
- Tevékenységfüggvények
- Ügyfélfüggvények
- Újrapróbálkozás szabályzatai (ha használják)
- Entitásfüggvények (ha használják)
Az API-nkénti teljes leképezésért tekintse meg az API-referenciát.
Névtérváltozások
// 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;
Függvényattribútum változásai
// Before (In-Process)
[FunctionName("MyOrchestrator")]
// After (Isolated Worker)
[Function(nameof(MyOrchestrator))]
Az Orchestrator függvények változásai
Előtte (Folyamatban):
[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 };
}
After (izolált munkafolyamat):
[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 };
}
Főbb különbségek
| Szempont | Folyamatban | Izolált munkás |
|---|---|---|
| Környezet típusa | IDurableOrchestrationContext |
TaskOrchestrationContext |
| Logger |
ILogger Paraméter |
context.CreateReplaySafeLogger() |
| Attribútum | [FunctionName] |
[Function] |
Tevékenységfüggvény változásai
Előtte (Folyamatban):
[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;
}
After (izolált munkafolyamat):
[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;
}
Ügyfélfunkció változásai
Előtte (Folyamatban):
[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);
}
After (izolált munkafolyamat):
[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);
}
Ügyféltípus-módosítások
| Folyamatban | Izolált munkavégző |
|---|---|
IDurableOrchestrationClient |
DurableTaskClient |
StartNewAsync() |
ScheduleNewOrchestrationInstanceAsync() |
CreateCheckStatusResponse() |
CreateCheckStatusResponseAsync() |
HttpRequest / IActionResult |
HttpRequestData / HttpResponseData |
Szabályzatmódosítások újrapróbálkozása
A folyamatban használt RetryOptions a CallActivityWithRetryAsync-vel. Az izolált dolgozó a standard TaskOptions-t használjaCallActivityAsync.
Előtte (Folyamatban):
var retryOptions = new RetryOptions(
firstRetryInterval: TimeSpan.FromSeconds(5),
maxNumberOfAttempts: 3);
string result = await context.CallActivityWithRetryAsync<string>(
"MyActivity", retryOptions, input);
After (izolált munkafolyamat):
var retryOptions = new TaskOptions(
new TaskRetryOptions(new RetryPolicy(
maxNumberOfAttempts: 3,
firstRetryInterval: TimeSpan.FromSeconds(5))));
string result = await context.CallActivityAsync<string>(
"MyActivity", input, retryOptions);
Entitásfunkció változások
Előtte (Folyamatban):
[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;
}
}
After (izolált munkafolyamat):
[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;
}
A kompatibilitástörő viselkedés változásai
A migrált alkalmazás tesztelése előtt tekintse át ezeket a módosításokat. Az API-nkénti teljes leképezéshez tekintse meg az API-referenciát.
Warning
A szerializálás alapértelmezése megváltozott: Az izolált feldolgozó alapértelmezés szerint most System.Text.Json-t használ Newtonsoft.Json helyett. Ha az orchestration-ök összetett objektumokat kezelnek, gondosan tesztelje a szerializálást. A konfigurációs beállítások JSON-szerializálási különbségeit lásd.
Warning
ContinueAsNew alapértelmezett változás: Az preserveUnprocessedEvents paraméter alapértelmezett értéke megváltozott false (2.x)-ről true (izolált)-ra. Ha az orchestráció ContinueAsNew és a feldolgozatlan események elvetésére támaszkodik, adja át explicit módon a preserveUnprocessedEvents: false.
Note
RestartAsync alapértelmezett módosítása: Az restartWithNewInstanceId paraméter alapértelmezése megváltozott a true (2.x) értékről false (izolált) értékre. Ha a kód meghívja RestartAsync, és függ attól, hogy új példányazonosító generálódjon, akkor explicit módon adja át restartWithNewInstanceId: true.
Egyéb jelentős változások:
-
Az entitás-proxyk el lettek távolítva –
CreateEntityProxy<T>nem érhető el. HasználjaEntities.CallEntityAsyncvagyEntities.SignalEntityAsyncközvetlenül. -
A feladatközpontok közötti műveletek el lettek távolítva – Az elfogadott
taskHubName/connectionNametúlterhelések nem érhetők el. Csak az azonos feladatközponti műveletek támogatottak. -
Az orchestrációs előzmények áthelyezve –
DurableOrchestrationStatus.Historymár nem szerepel az állapot objektumban. Használja aDurableTaskClient.GetOrchestrationHistoryAsync.
local.settings.jsonfrissítése
A kulcs változtatása FUNCTIONS_WORKER_RUNTIME-ról dotnet-ra setting dotnet-isolated:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
}
}
Note
A háttérrendszer konfigurációját (Azure Storage, MSSQL, Netherite vagy Durable Task Scheduler) az áttelepítés nem változtatja meg. Tartsa meg a meglévő tárolási beállításokat.
Helyi tesztelés
Futtassa helyileg a függvényalkalmazást, és ellenőrizze, hogy az összes vezénylés, tevékenység és entitás megfelelően működik-e.
func start
Funkciók ellenőrzése
Tesztelje a következő forgatókönyveket a megfelelő módon:
- Folyamatvezérlés indítása HTTP-eseményindítóval
- A vezénylés állapotának figyelése
- A tevékenység végrehajtási megrendelésének ellenőrzése
- Entitásműveletek tesztelése, ha vannak
- Az Application Insights telemetriájának ellenőrzése
Telepítés az Azure-ra
Ajánlott: Üzembehelyezési pontok használata
Üzembehelyezési pontok használata az állásidő minimalizálásához:
- Hozzon létre egy átmeneti pontot a függvényalkalmazáshoz.
-
Az előkészítési pont konfigurációjának frissítése:
- Állítsa be
FUNCTIONS_WORKER_RUNTIME-tdotnet-isolated-re. - Szükség esetén frissítse .NET veremverziót.
- Állítsa be
- Telepítse a migrált kódot az előkészítési résbe.
- Tesztelje alaposan az előkészítési ponton.
- Slot cserét hajtson végre a változtatások éles környezetbe viteléhez.
Alkalmazásbeállítások frissítése
A Azure portálon vagy a parancssori felületen:
az functionapp config appsettings set \
--name <FUNCTION_APP_NAME> \
--resource-group <RESOURCE_GROUP> \
--settings FUNCTIONS_WORKER_RUNTIME=dotnet-isolated
Veremkonfiguráció frissítése
Ha másik .NET verziót céloz meg:
az functionapp config set \
--name <FUNCTION_APP_NAME> \
--resource-group <RESOURCE_GROUP> \
--net-framework-version v8.0
Gyakori migrációs problémák
Probléma: Szerelvénybetöltési hibák
Tünet:Could not load file or assembly hibák.
Solution: Győződjön meg arról, hogy az összes Microsoft.Azure.WebJobs.* csomaghivatkozást eltávolítja, és azokat izolált feldolgozó-megfelelőkre cseréli.
Probléma: A kötési attribútum nem található
Tünet:The type or namespace 'QueueTrigger' could not be found
Megoldás: Adja hozzá a megfelelő bővítménycsomagot, és frissítse a using utasításokat.
// Add using statement
using Microsoft.Azure.Functions.Worker;
// Install package
// dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues
Probléma: Az IDurableOrchestrationContext nem található
Tünet:The type or namespace 'IDurableOrchestrationContext' could not be found
Megoldás: Cserélje le a következőre TaskOrchestrationContext:
using Microsoft.DurableTask;
[Function(nameof(MyOrchestrator))]
public static async Task MyOrchestrator([OrchestrationTrigger] TaskOrchestrationContext context)
{
// ...
}
Probléma: JSON szerializálási különbségek
Tünet: Szerializálási hibák vagy váratlan adatformátumok
Megoldás: Az izolált modell alapértelmezés szerint használ System.Text.Json . Szerializálás konfigurálása a következőben Program.cs:
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services => {
services.Configure<JsonSerializerOptions>(options => {
options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});
})
.Build();
A Newtonsoft.Json használatához:
services.Configure<WorkerOptions>(options => {
options.Serializer = new NewtonsoftJsonObjectSerializer();
});
Probléma: Egyéni szerializálási beállítások áttelepítése
Tünet: A folyamaton belüli modellben használta a IMessageSerializerSettingsFactory , és az elszigetelt munkavállalóban az ennek megfelelőre van szüksége.
Megoldás: A feldolgozószintű szerializáló Program.cs konfigurálása. További részletekért tekintse meg a viselkedési változások szakaszát az API-referenciában és az Adatszerializálás és tartósság a Durable Functionsben.
A Newtonsoft.Json használata egyéni beállításokkal:
// 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();
Note
Ehhez a megközelítéshez Newtonsoft.Json és Azure.Core.Serialization NuGet-csomagokra van szükség.
Checklist
Ezzel az ellenőrzőlistát használva biztosíthatja a teljes migrálást:
- Projektfájlt frissítettem a
<OutputType>Exe</OutputType> -
Microsoft.NET.Sdk.Functionshelyett munkacsomagok -
Microsoft.Azure.WebJobs.Extensions.DurableTaskizolált csomagra cserélve - Gazdagépkonfigurációval létrehozva
Program.cs - Eltávolított
FunctionsStartuposztály (ha van) - Frissítettem az összes
[FunctionName][Function]-re. -
IDurableOrchestrationContexthelyébeTaskOrchestrationContextlépett -
IDurableOrchestrationClienthelyébeDurableTaskClientlépett - Frissített naplózás a DI vagy a
FunctionContext - Futtatókörnyezettel
local.settings.jsonfrissítvedotnet-isolated - Az összes
Microsoft.Azure.WebJobs.*eltávolítása utasítások használatával -
Microsoft.Azure.Functions.Workerutasításokkal hozzáadva - A
CreateEntityProxy<T>közvetlenCallEntityAsync, /, ésSignalEntityAsynchívásokkal lett lecserélve. - Feladatközpontok közötti műveleti túlterhelések lecserélése (ha van használatban)
- Kötegelt
GetStatusAsync/PurgeInstanceHistoryAsyncazonosítós hívásokat felváltva szűrőalapú vagy egyéni hívásokkal - Migrált
DurableOrchestrationStatus.Historyhozzáférés aGetOrchestrationHistoryAsync - Frissített entitáskonstruktor-paramok
DispatchAsynca DI használatához - Az összes függvény helyi tesztelése
- Üzembe helyezve az előzetes helyen, majd ellenőrizve
- Felcserélve az éles környezetbe
Következő lépések
- Folyamatban az izolált feldolgozói API-leképezés – teljes API-referencia a migráláshoz
- Az .NET izolált feldolgozású Durable Functions áttekintése
- Durable Functions verziók és migrálási útmutató