在隔離式背景工作模型中執行 C# Azure Functions 的指南
本文會介紹如何使用隔離式背景工作模型在 .NET 中搭配使用 Azure Functions。 此模型可讓您的專案在獨立於其他執行階段元件的情況下,以 .NET 版本為目標。 如需支援的特定 .NET 版本資訊,請參閱支援的版本。
使用下列連結立即開始建置 .NET 隔離式背景工作模型函式。
開始使用 | 概念 | 範例 |
---|---|---|
若要深入了解如何將隔離式背景工作模型專案部署至 Azure,請參閱部署至 Azure Functions。
隔離式背景工作模型的優點
有兩種模式可讓您執行 .NET 類別庫函式:在與 Functions 主機執行階段相同的處理序中 (同處理序),或在隔離式背景工作處理序中。 當您的 .NET 函式在隔離式背景工作處理序中執行時,您可以利用下列優點:
- 衝突較少:因為您的函式會在個別處理序中執行,所以您應用程式中所使用的組件不會與主機處理序所使用相同組件的不同版本衝突。
- 完整控制處理序:您可以控制應用程式的啟動,這表示您可以管理所使用的設定,以及啟動的中介軟體。
- 標準相依性插入:因為您可以完全控制處理序,所以您可以使用目前的 .NET 行為進行相依性插入,並將中介軟體併入函數應用程式中。
- .NET 版本彈性:在主機處理序外部執行,表示您的函式可以在非 Functions 執行階段原生支援的 .NET 版本上執行,包括 .NET Framework。
如果您有在同處理序執行的現有 C# 函數應用程式,您必須遷移應用程式以運用這些優點。 如需詳細資訊,請參閱將 .NET 應用程式從同處理序模型遷移至隔離式背景工作模型。
如需兩個模型之間的綜合比較,請參閱同處理序和隔離式背景工作處理序 .NET Azure Functions 之間的差異。
支援的版本
Functions 執行階段的版本支援 .NET 特定版本。 若要深入瞭解 Functions 版本,請參閱 Azure Functions 執行階段版本概觀。 版本支援也取決於函式執行同處理序或隔離式背景工作處理序。
注意
若要瞭解如何變更函數應用程式所使用的 Functions 執行階段版本,請參閱檢視及更新目前的執行階段版本。
下表顯示可與 Functions 特定版本搭配使用的最高層級 .NET 或 .NET Framework。
Functions 執行階段版本 | 隔離式背景工作模型 | 進程內模型4 |
---|---|---|
Functions 4.x1 | .NET 9.0 .NET 8.0 .NET Framework 4.82 |
.NET 8.0 |
Functions 1.x3 | n/a | .NET Framework 4.8 |
1.NET 6 以前在兩種型號上都受到支援,但已於 2024 年 11 月 12 日終止官方支援 。 .NET 7 先前在隔離式背景工作角色模型上受到支援,但於 2024 年 5 月 14 日終止正式支援。
2 建置程式也需要 .NET SDK。
3 2026 年 9 月 14 日 Azure Functions 運行時間 1.x 版的支持結束。 如需詳細資訊,請參閱此支援公告。 如需持續的完整支援,您應該將應用程式移轉至 4.x 版。
4 支援會在 2026 年 11 月 10 日結束處理模型。 如需詳細資訊,請參閱此支援公告。 如需持續的完整支援,您應該將應用程式移轉至隔離式背景工作角色模型。
如需有關 Azure Functions 版本的最新新聞,包括移除特定舊版次要版本,請持續關注 Azure App Service 公告。
專案結構
適用於 Azure Functions 且使用隔離式背景工作模型的 .NET 專案基本上是以支援的 .NET 執行階段為目標的 .NET 主控台應用程式專案。 下列是任何 .NET 隔離式專案所需的基本檔案:
- 定義專案和相依性的 C# 專案檔 (.csproj)。
- Program.cs 檔案,這是應用程式的進入點。
- 定義函式的任何程式碼檔案。
- host.json 檔案,定義專案中函式所共用的設定。
- local.settings.json 檔案,定義在機器本機上執行時,專案所使用的環境變數。
如需完整範例,請參閱 .NET 8 範例專案和 .NET Framework 4.8 範例專案。
套件參考
針對核心功能與繫結延伸模組,適用於 Azure Functions 且使用隔離式背景工作模型的 .NET 專案會使用一組唯一的套件。
核心套件
需要下列套件,才能在隔離式背景工作處理序中執行 .NET 函式:
2.x 版
2.x 版的核心套件會變更支持的架構,並從這些更新版本引進新的 .NET API 支援。 當您以 .NET 9 或更新版本為目標時,您的應用程式必須參考這兩個套件的 2.0.0 版或更新版本。
更新至 2.x 版本時,請注意下列變更:
- 從 Microsoft.Azure.Functions.Worker.Sdk 2.0.0 版開始:
- SDK 包含 SDK 容器組建的預設 組態。
- SDK 包含安裝 Azure Functions Core Tools 時的支援
dotnet run
。 在 Windows 上,核心工具必須透過 NPM 以外的機制來安裝。
- 從 2.0.0 版 開始,Microsoft.Azure.Functions.Worker:
- 此版本新增 對
IHostApplicationBuilder
的支援。 本指南中的一些範例包含索引標籤,以使用IHostApplicationBuilder
來顯示替代專案。 這些範例需要 2.x 版本。 - 在開發環境中執行時,預設會包含服務提供者範圍驗證。 此行為符合 Core ASP.NET。
- 此選項
EnableUserCodeException
預設為啟用。 屬性現在標示為過時。 - 此選項
IncludeEmptyEntriesInMessagePayload
預設為啟用。 啟用此選項后,代表集合的觸發承載一律包含空白專案。 例如,如果訊息在沒有本文的情況下傳送,則觸發程序數據仍會出現string[]
空白專案。 包含空白項目有助於使用函式可能也會參考的元數據陣列進行交叉參考。 您可以在服務組態中WorkerOptions
將 設定IncludeEmptyEntriesInMessagePayload
為false
,以停用此行為。 - 類別
ILoggerExtensions
會重新命名為FunctionsLoggerExtensions
。 重新命名可防止在 實例上使用時發生模棱兩可的ILogger
呼叫錯誤LogMetric()
。 - 對於使用
HttpResponseData
應用程式,WriteAsJsonAsync()
方法將不再將狀態代碼設定為200 OK
。 在 1.x 中,這會覆寫已設定的其他錯誤碼。
- 此版本新增 對
- 2.x 版本會卸除 .NET 5 TFM 支援。
延伸模組套件
因為 .NET 隔離式背景工作處理序會使用不同的繫結類型,所以其需要一組唯一的繫結延伸模組套件。
您可以在 Microsoft.Azure.Functions.Worker.Extensions 底下找到這些延伸模組套件。
啟動和設定
當您使用隔離的背景工作模型時,您可以存取函式應用程式的啟動,這通常位於 Program.cs
中。 您必須負責建立和啟動自己的主機執行個體。 因此,您也可以直接存取應用程式的設定管道。 有了 .NET Functions 隔離式背景工作處理序,您可以更輕鬆地新增設定、插入相依性,以及執行您自己的中介軟體。
下列程式碼洗善 HostBuilder 管道的範例:
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(s =>
{
s.AddApplicationInsightsTelemetryWorkerService();
s.ConfigureFunctionsApplicationInsights();
s.AddSingleton<IHttpResponderService, DefaultHttpResponderService>();
s.Configure<LoggerFilterOptions>(options =>
{
// The Application Insights SDK adds a default logging filter that instructs ILogger to capture only Warning and more severe logs. Application Insights requires an explicit override.
// Log levels can also be configured using appsettings.json. For more information, see https://learn.microsoft.com/en-us/azure/azure-monitor/app/worker-service#ilogger-logs
LoggerFilterRule? toRemove = options.Rules.FirstOrDefault(rule => rule.ProviderName
== "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
if (toRemove is not null)
{
options.Rules.Remove(toRemove);
}
});
})
.Build();
此程式碼需要 using Microsoft.Extensions.DependencyInjection;
。
在 IHostBuilder
上呼叫 Build()
之前,您應該:
- 如果使用 ASP.NET Core 整合,則呼叫
ConfigureFunctionsWebApplication()
,否則呼叫ConfigureFunctionsWorkerDefaults()
。 如需這些選項的詳細資訊,請參閱 HTTP 觸發程序。
如果您要使用 F# 撰寫應用程式,則某些觸發程序和繫結延伸模組需要額外設定。 當您打算在 F# 應用程式中使用延伸模組時,請參閱 Blob 延伸模組、資料表延伸模組和 Cosmos DB 延伸模組的設定文件。 - 設定專案所需的任何服務或應用程式設定。 如需詳細資訊,請參閱設定。
如果您打算使用 Application Insights,則必須在ConfigureServices()
委派中呼叫AddApplicationInsightsTelemetryWorkerService()
和ConfigureFunctionsApplicationInsights()
。 如需詳細資訊,請參閱 Application Insights。
如果您的專案以 .NET Framework 4.8 為目標,則也需要在建立 HostBuilder 之前新增 FunctionsDebugger.Enable();
。 這應該是方法 Main()
的第一行。 如需詳細資訊,請參閱以 .NET Framework 為目標時進行偵錯。
HostBuilder 可用來建置並傳回完整初始化的 IHost
執行個體,而您會以非同步方式執行該執行個體以啟動函數應用程式。
await host.RunAsync();
組態
您使用的產生器類型會決定如何設定應用程式。
ConfigureFunctionsWorkerDefaults 方法可用來新增函數應用程式執行所需的設定。 方法包含下列功能:
- 預設的轉換器集合。
- 設定預設 JsonSerializerOptions 以忽略屬性名稱的大小寫。
- 與 Azure Functions 記錄整合。
- 輸出繫結中介軟體和功能。
- 函式執行中介軟體。
- 預設 gRPC 支援。
.ConfigureFunctionsWorkerDefaults()
擁有主機產生器管道的存取權,表示您也可以在初始化期間設定任何應用程式特定的設定。 您可以在 HostBuilder 上呼叫 ConfigureAppConfiguration 方法一或多次,以新增程式代碼所需的任何組態來源。 若要深入瞭解應用程式設定,請參閱 ASP.NET Core 中的設定。
這些設定僅適用於您撰寫的背景工作程序代碼,而且它們不會直接影響 Functions 主機或觸發程式和系結的設定。 若要變更函式主機或觸發程序以及繫結設定,您仍然需要使用 host.json 檔案。
注意
自訂組態來源無法用於設定觸發程序和繫結。 觸發程序和繫結組態必須可供 Functions 平台使用,而不只是您的應用程式程式碼。 您可以透過應用程式設定、Key Vault 參考或應用程式組態參考功能來提供此組態。
相依性插入
隔離的背景工作模型會使用標準 .NET 機制來插入服務。
當您使用 HostBuilder
時,請在主機產生器上呼叫 ConfigureServices,並使用 IServiceCollection 上的擴充方法來插入特定服務。 下列範例會插入單一資料庫服務相依性:
.ConfigureServices(services =>
{
services.AddSingleton<IHttpResponderService, DefaultHttpResponderService>();
})
此程式碼需要 using Microsoft.Extensions.DependencyInjection;
。 若要深入瞭解,請參閱 ASP.NET Core 中的相依性插入。
註冊 Azure 用戶端
相依性插入可用來與其他 Azure 服務互動。 您可以使用 Microsoft.Extensions.Azure 套件,從適用於 .NET 的 Azure SDK 插入用戶端。 安裝套件之後,請在 Program.cs
中的服務集合上呼叫 AddAzureClients()
來註冊用戶端。 下列範例會設定 Azure Blob 的具名用戶端:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices((hostContext, services) =>
{
services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddBlobServiceClient(hostContext.Configuration.GetSection("MyStorageConnection"))
.WithName("copierOutputBlob");
});
})
.Build();
host.Run();
下列範例示範如何使用此註冊和 SDK 類型,透過插入的用戶端,將 Blob 內容以資料流形式從一個容器複製到另一個容器:
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Logging;
namespace MyFunctionApp
{
public class BlobCopier
{
private readonly ILogger<BlobCopier> _logger;
private readonly BlobContainerClient _copyContainerClient;
public BlobCopier(ILogger<BlobCopier> logger, IAzureClientFactory<BlobServiceClient> blobClientFactory)
{
_logger = logger;
_copyContainerClient = blobClientFactory.CreateClient("copierOutputBlob").GetBlobContainerClient("samples-workitems-copy");
_copyContainerClient.CreateIfNotExists();
}
[Function("BlobCopier")]
public async Task Run([BlobTrigger("samples-workitems/{name}", Connection = "MyStorageConnection")] Stream myBlob, string name)
{
await _copyContainerClient.UploadBlobAsync(name, myBlob);
_logger.LogInformation($"Blob {name} copied!");
}
}
}
此範例中的 ILogger<T>
也會透過相依性插入取得,因此會自動註冊。 若要深入了解記錄的設定選項,請參閱記錄。
提示
在 Program.cs
和函式中,此範例使用常值字串作為用戶端名稱。 請考慮改用函式類別上定義的共用常數字串。 例如,您可以在這兩個位置中新增 public const string CopyStorageClientName = nameof(_copyContainerClient);
,然後參考 BlobCopier.CopyStorageClientName
。 您也可以使用函式來定義設定區段名稱,而不是在 Program.cs
中定義。
中介軟體
隔離式背景工作角色模型也支援中介軟體註冊,方法同樣是使用類似於 ASP.NET 中存在的模型。 此模型可讓您將邏輯插入引動管道,以及在函式執行前後插入。
ConfigureFunctionsWorkerDefaults 擴充方法具有多載,可讓您註冊自己的中介軟體,如下列範例所示。
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(workerApplication =>
{
// Register our custom middlewares with the worker
workerApplication.UseMiddleware<ExceptionHandlingMiddleware>();
workerApplication.UseMiddleware<MyCustomMiddleware>();
workerApplication.UseWhen<StampHttpHeaderMiddleware>((context) =>
{
// We want to use this middleware only for http trigger invocations.
return context.FunctionDefinition.InputBindings.Values
.First(a => a.Type.EndsWith("Trigger")).Type == "httpTrigger";
});
})
.Build();
UseWhen
延伸模組可用於註冊有條件地執行的中介軟體。 您必須將傳回布林值的述詞傳遞給此方法,而中介軟體會在述詞的傳回值為 true
時參與叫用處理管線。
FunctionContext 上的下列擴充方法可讓您更輕鬆地在隔離式模型中使用中介軟體。
方法 | 描述 |
---|---|
GetHttpRequestDataAsync |
取得由 HTTP 觸發程序呼叫時的 HttpRequestData 執行個體。 這個方法會傳回 ValueTask<HttpRequestData?> 的執行個體,當您想要讀取訊息資料時很有用,例如要求標頭和 Cookie。 |
GetHttpResponseData |
取得由 HTTP 觸發程序呼叫時的 HttpResponseData 執行個體。 |
GetInvocationResult |
取得 InvocationResult 的執行個體,表示目前函式執行的結果。 使用 Value 屬性視需要取得或設定值。 |
GetOutputBindings |
取得目前函式執行的輸出繫結項目。 此方法結果中的每個項目都是類型 OutputBindingData 。 您可以使用 Value 屬性視需要取得或設定值。 |
BindInputAsync |
繫結所要求 BindingMetadata 執行個體的輸入繫結項目。 例如,當您的函式具有需要由中介軟體使用的 BlobInput 輸入繫結時,便可以使用這個方法。 |
這是中介軟體實作的範例,其會讀取 HttpRequestData
執行個體,並在函式執行期間更新 HttpResponseData
執行個體:
internal sealed class StampHttpHeaderMiddleware : IFunctionsWorkerMiddleware
{
public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
{
var requestData = await context.GetHttpRequestDataAsync();
string correlationId;
if (requestData!.Headers.TryGetValues("x-correlationId", out var values))
{
correlationId = values.First();
}
else
{
correlationId = Guid.NewGuid().ToString();
}
await next(context);
context.GetHttpResponseData()?.Headers.Add("x-correlationId", correlationId);
}
}
此中介軟體會檢查是否有特定要求標頭 (x-correlationId),並於存在時使用標頭值來為回應標頭加上戳記。 否則,其會產生新的 GUID 值,並使用該值來為回應標頭加上戳記。 如需在函數應用程式中使用自訂中介軟體的更完整範例,請參閱自訂中介軟體參考範例。
自訂 JSON 序列化
隔離式背景工作角色模型預設會使用 System.Text.Json
。 您可以將服務設定為 Program.cs
檔案的一部分,以自訂序列化程式的行為。 本節涵蓋一般用途串行化,且不會影響 使用 ASP.NET Core 整合的 HTTP 觸發程式 JSON 串行化,而必須個別設定。
下列範例示範如何使用 ConfigureFunctionsWebApplication
,但其也適用於 ConfigureFunctionsWorkerDefaults
:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication((IFunctionsWorkerApplicationBuilder builder) =>
{
builder.Services.Configure<JsonSerializerOptions>(jsonSerializerOptions =>
{
jsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
jsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
jsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
// override the default value
jsonSerializerOptions.PropertyNameCaseInsensitive = false;
});
})
.Build();
host.Run();
您可能想要改用 JSON.NET (Newtonsoft.Json
) 進行串行化。 若要這樣做,您會安裝 Microsoft.Azure.Core.NewtonsoftJson
套件。 然後,在服務註冊中,您會在 WorkerOptions
組態上重新指派 Serializer
屬性。 下列範例示範如何使用 ConfigureFunctionsWebApplication
,但其也適用於 ConfigureFunctionsWorkerDefaults
:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication((IFunctionsWorkerApplicationBuilder builder) =>
{
builder.Services.Configure<WorkerOptions>(workerOptions =>
{
var settings = NewtonsoftJsonObjectSerializer.CreateJsonSerializerSettings();
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
settings.NullValueHandling = NullValueHandling.Ignore;
workerOptions.Serializer = new NewtonsoftJsonObjectSerializer(settings);
});
})
.Build();
host.Run();
辨識為函式的方法
函式方法是公用類別的公用方法,方法會套用 Function
屬性,而輸入參數會套用觸發程序屬性,如下列範例所示:
[Function(nameof(QueueFunction))]
[QueueOutput("output-queue")]
public string[] Run([QueueTrigger("input-queue")] Album myQueueItem, FunctionContext context)
觸發程序屬性可指定觸發程序類型,並將輸入資料繫結至方法參數。 上述範例函式是由佇列訊息所觸發,該佇列訊息會接著傳遞給 myQueueItem
參數中的方法。
Function
屬性會將方法標記為函式進入點。 名稱在專案中不可重複,必須以字母開頭,且只能包含字母、數字、_
與 -
,長度不可超過 127 個字元。 專案範本通常會建立名為 Run
的方法,不過任何有效的 C# 方法名稱都能成為方法名稱。 方法必須是公用類別的公用成員。 其通常應該是執行個體方法,以便透過相依性插入傳入服務。
函數參數
以下是可以包含在函式方法簽章中的一些參數:
執行內容
.NET 隔離式會將 FunctionContext 物件傳遞至函式方法。 此物件可讓您藉由呼叫 GetLogger 方法並提供 categoryName
字串,取得 ILogger
執行個體以寫入記錄。 您可以使用此內容來取得 ILogger
,而不需要使用相依性插入。 若要深入瞭解,請參閱記錄。
取消權杖
可以接受 CancellationToken 參數的函式,讓作業系統能夠在函式即將終止時通知您的程式碼。 您可以使用此通知來確保函數不會在讓資料維持不一致狀態的情況下意外終止。
在隔離式背景工作處理序中執行時,.NET 函式會支援取消權杖。 下列範例會在收到取消要求時引發例外狀況:
[Function(nameof(ThrowOnCancellation))]
public async Task ThrowOnCancellation(
[EventHubTrigger("sample-workitem-1", Connection = "EventHubConnection")] string[] messages,
FunctionContext context,
CancellationToken cancellationToken)
{
_logger.LogInformation("C# EventHub {functionName} trigger function processing a request.", nameof(ThrowOnCancellation));
foreach (var message in messages)
{
cancellationToken.ThrowIfCancellationRequested();
await Task.Delay(6000); // task delay to simulate message processing
_logger.LogInformation("Message '{msg}' was processed.", message);
}
}
下列範例會在收到取消要求時執行清除動作:
[Function(nameof(HandleCancellationCleanup))]
public async Task HandleCancellationCleanup(
[EventHubTrigger("sample-workitem-2", Connection = "EventHubConnection")] string[] messages,
FunctionContext context,
CancellationToken cancellationToken)
{
_logger.LogInformation("C# EventHub {functionName} trigger function processing a request.", nameof(HandleCancellationCleanup));
foreach (var message in messages)
{
if (cancellationToken.IsCancellationRequested)
{
_logger.LogInformation("A cancellation token was received, taking precautionary actions.");
// Take precautions like noting how far along you are with processing the batch
_logger.LogInformation("Precautionary activities complete.");
break;
}
await Task.Delay(6000); // task delay to simulate message processing
_logger.LogInformation("Message '{msg}' was processed.", message);
}
}
繫結
繫結是使用方法、參數和傳回型別的屬性來定義。 繫結能夠以字串、陣列和可序列化的型別提供資料,例如簡單的 CLR 物件 (POCO)。 針對某些繫結延伸模組,您也可以繫結至服務 SDK 中定義的服務專屬型別。
針對 HTTP 觸發程序,請參閱 HTTP 觸發程序一節。
如需搭配隔離式背景工作處理序函式使用觸發程序與繫結的一組完整參考範例,請參閱繫結延伸模組參考範例。
輸入繫結
函式可以有零個或多個輸入繫結,可將資料傳遞至函式。 如同觸發程序,輸入繫結是藉由將繫結屬性套用至輸入參數來定義。 當函式執行時,執行階段會嘗試取得繫結中指定的資料。 所要求的資料通常取決於觸發程序使用繫結參數所提供的資訊。
輸出繫結
若要寫入輸出繫結,您必須將輸出繫結屬性套用至函式方法,以定義如何寫入繫結服務。 方法傳回的值會寫入輸出繫結。 例如,下列範例會使用輸出繫結,將字串值寫入名為 output-queue
的訊息佇列:
[Function(nameof(QueueFunction))]
[QueueOutput("output-queue")]
public string[] Run([QueueTrigger("input-queue")] Album myQueueItem, FunctionContext context)
{
// Use a string array to return more than one message.
string[] messages = {
$"Album name = {myQueueItem.Name}",
$"Album songs = {myQueueItem.Songs}"};
_logger.LogInformation("{msg1},{msg2}", messages[0], messages[1]);
// Queue Output messages
return messages;
}
多個輸出繫結
寫入至輸出繫結的資料一律是函式的傳回值。 如果您需要寫入多個輸出繫結,則必須建立自訂傳回型別。 這個傳回型別必須套用輸出繫結屬性至類別的一或多個屬性。 下列範例是使用 ASP.NET Core 整合 的 HTTP 觸發函式,其會同時寫入 HTTP 回應和佇列輸出繫結:
public class MultipleOutputBindings
{
private readonly ILogger<MultipleOutputBindings> _logger;
public MultipleOutputBindings(ILogger<MultipleOutputBindings> logger)
{
_logger = logger;
}
[Function("MultipleOutputBindings")]
public MyOutputType Run([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req)
{
_logger.LogInformation("C# HTTP trigger function processed a request.");
var myObject = new MyOutputType
{
Result = new OkObjectResult("C# HTTP trigger function processed a request."),
MessageText = "some output"
};
return myObject;
}
public class MyOutputType
{
[HttpResult]
public IActionResult Result { get; set; }
[QueueOutput("myQueue")]
public string MessageText { get; set; }
}
}
針對具有 ASP.NET Core 整合的多個輸出繫結使用自訂傳回類型時,您必須將 [HttpResult]
屬性新增至提供結果的屬性。 使用 SDK 1.17.3-preview2 或更新版本,以及 3.2.0 版或更新版本的 HTTP 延伸模組和 1.3.0 版或更新版本的 ASP.NET Core 延伸模組時,可以使用 HttpResult
屬性。
SDK 類型
對於某些服務專屬的繫結類型,可以使用來自服務 SDK 和架構的類型來提供繫結資料。 這些類型提供的功能超過序列化字串或普通舊 CLR 物件 (POCO) 所能提供的功能。 若要使用較新的類型,您的物件必須更新,才能使用較新版本的核心相依性。
Dependency | 版本需求 |
---|---|
Microsoft.Azure.Functions.Worker | 1.18.0 或更新版本 |
Microsoft.Azure.Functions.Worker.Sdk | 1.13.0 或更新版本 |
在機器本機上測試 SDK 類型時,您也需要使用 Azure Functions Core Tools 4.0.5000 版或更新版本。 您可以使用 func version
命令來檢查目前版本。
每個觸發程序和繫結延伸模組也有其自己的最低版本需求,如延伸模組參考文章中所述。 下列服務專屬繫結提供 SDK 類型:
服務 | 觸發程序 | 輸入繫結 | 輸出繫結 |
---|---|---|---|
Azure Blob | 正式推出 | 正式推出 | 不建議的 SDK 類型。1 |
Azure 佇列 | 正式推出 | 輸入繫結不存在 | 不建議的 SDK 類型。1 |
Azure 服務匯流排 | 正式推出 | 輸入繫結不存在 | 不建議的 SDK 類型。1 |
Azure 事件中樞 | 正式推出 | 輸入繫結不存在 | 不建議的 SDK 類型。1 |
Azure Cosmos DB | 未使用的 SDK 類型2 | 正式推出 | 不建議的 SDK 類型。1 |
Azure 資料表 | 觸發程序不存在 | 正式推出 | 不建議的 SDK 類型。1 |
事件格線 | 正式推出 | 輸入繫結不存在 | 不建議的 SDK 類型。1 |
1 針對您將使用 SDK 類型的輸出案例,您應該直接建立及使用 SDK 用戶端,而不是使用輸出繫結。 如需相依性插入範例,請參閱註冊 Azure 用戶端。
2 Cosmos DB 觸發程序會使用 Azure Cosmos DB 變更摘要,並將變更摘要項目公開為 JSON 可序列化類型。 此案例預設沒有 SDK 類型。
注意
使用依賴觸發程序資料的繫結運算式時,無法使用觸發程序本身的 SDK 類型。
HTTP 觸發程序
HTTP 觸發程序允許 HTTP 要求叫用函式。 有兩種不同的方法可以使用:
- ASP.NET Core 整合模型,其使用 ASP.NET Core 開發人員熟悉的概念
- 內建模型,不需要額外的相依性,並針對 HTTP 要求和回應使用自訂類型。 此方法會與先前的 .NET 隔離式背景工作應用程式維持回溯相容性。
ASP.NET Core 整合
本節說明如何搭配來自 ASP.NET Core 的類型使用基礎 HTTP 要求和回應物件,包括 HttpRequest、HttpResponse 和 IActionResult。 此模型不適用於以 .NET Framework 為目標的應用程式,其應該改用內建模型。
注意
並非所有 ASP.NET Core 的功能都會由此模型公開。 具體而言,ASP.NET Core 中介軟體管線和路由功能都無法使用。 ASP.NET Core 整合需要您使用更新的套件。
若要啟用 HTTP 的 ASP.NET Core 整合:
將專案中的參考新增至 Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore 套件 1.0.0 版或更新版本。
更新您的專案以使用這些特定的套件版本:
- Microsoft.Azure.Functions.Worker.Sdk 1.11.0 版。 或更新版本
- Microsoft.Azure.Functions.Worker 1.16.0 版或更新版本。
在您的
Program.cs
檔案中,更新主機產生器組態以呼叫ConfigureFunctionsWebApplication()
。 如果否則會使用該方法,這會取代ConfigureFunctionsWorkerDefaults()
。 下列範例顯示不含其他自訂的最低限度設定:using Microsoft.Azure.Functions.Worker; using Microsoft.Extensions.Hosting; var host = new HostBuilder() .ConfigureFunctionsWebApplication() .Build(); host.Run();
更新任何現有的 HTTP 觸發程序函數,以使用 ASP.NET Core 類型。 此範例顯示用於簡單 "hello, world" 函式的標準
HttpRequest
和IActionResult
:[Function("HttpFunction")] public IActionResult Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req) { return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!"); }
使用 ASP.NET Core 整合進行 JSON 序列化
ASP.NET Core 有自己的序列化層級,且不受自訂一般序列化設定的影響。 若要自訂 HTTP 觸發程序所使用的序列化行為,您必須在服務註冊中包含 .AddMvc()
呼叫。 傳回 IMvcBuilder
可用來修改 ASP.NET Core 的 JSON 序列化設定。
雖然對於大部分的應用程式,您可以繼續使用 HttpRequestData
和使用 HttpResponsedata
ASP.NET 整合,但最好改用 HttpRequest
和 IActionResult
。 使用 HttpRequestData
/HttpResponseData
不會叫用 ASP.NET Core 串行化層,而是依賴 應用程式的一般背景工作角色串行化組態 。 不過,啟用 ASP.NET Core 整合時,您可能仍然需要新增組態。 ASP.NET Core 的預設行為是不允許同步 IO。 若要使用不支援異步 IO 的自訂串行化程式,例如 NewtonsoftJsonObjectSerializer
,您必須藉由 KestrelServerOptions
設定 來啟用應用程式的同步 IO。
下列範例示範如何使用此方法來設定 JSON.NET (Newtonsoft.Json
) 和 Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet 套件 以進行串行化:
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
services.AddMvc().AddNewtonsoftJson();
// Only needed if using HttpRequestData/HttpResponseData and a serializer that doesn't support asynchronous IO
// services.Configure<KestrelServerOptions>(options => options.AllowSynchronousIO = true);
})
.Build();
host.Run();
內建 HTTP 模型
在內建模型中,系統會將傳入的 HTTP 要求訊息轉譯成傳遞至函式的 HttpRequestData 物件。 這個物件會提供來自要求的資料,包括 Headers
、Cookies
、Identities
、URL
和選擇性訊息 Body
。 此物件是 HTTP 要求的表示法,但不會直接連線到基礎 HTTP 接聽程式或接收的訊息。
同樣地,函式會傳回 HttpResponseData 物件,該物件會提供用來建立 HTTP 回應的資料,包括訊息 StatusCode
、Headers
和選擇性的訊息 Body
。
下列範例示範 HttpRequestData
和 HttpResponseData
的用法:
[Function(nameof(HttpFunction))]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestData req,
FunctionContext executionContext)
{
var logger = executionContext.GetLogger(nameof(HttpFunction));
logger.LogInformation("message logged");
var response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
response.WriteString("Welcome to .NET isolated worker !!");
return response;
}
記錄
您可以使用或 ILogger
實體寫入記錄ILogger<T>
。 記錄器可以透過 ILogger<T>
或 ILoggerFactory 的相依性插入來取得:
public class MyFunction {
private readonly ILogger<MyFunction> _logger;
public MyFunction(ILogger<MyFunction> logger) {
_logger = logger;
}
[Function(nameof(MyFunction))]
public void Run([BlobTrigger("samples-workitems/{name}", Connection = "")] string myBlob, string name)
{
_logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Data: {myBlob}");
}
}
記錄器也可以從傳遞至函式的 FunctionContext 物件取得。 呼叫 GetLogger<T> 或 GetLogger 方法,並傳遞字串值,這是記錄寫入所在類別的名稱。 類別通常是寫入記錄所在特定函式的名稱。 若要深入瞭解類別,請參閱監視文章。
使用 ILogger<T>
與 ILogger
方法來寫入各種記錄層級,例如 LogWarning
或 LogError
。 若要深入瞭解記錄層級,請參閱監視文章。 您可以藉由註冊篩選,來為新增至程式碼的元件自訂記錄層級:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(services =>
{
// Registers IHttpClientFactory.
// By default this sends a lot of Information-level logs.
services.AddHttpClient();
})
.ConfigureLogging(logging =>
{
// Disable IHttpClientFactory Informational logs.
// Note -- you can also remove the handler that does the logging: https://github.com/aspnet/HttpClientFactory/issues/196#issuecomment-432755765
logging.AddFilter("System.Net.Http.HttpClient", LogLevel.Warning);
})
.Build();
在 Program.cs
中設定應用程式時,您也可以定義錯誤如何在記錄中呈現的行為。 默認行為取決於您所使用的產生器類型。
當您使用 HostBuilder
時,根據預設,程式代碼擲回的例外狀況最後會包裝在 中 RpcException
。 若要移除這個額外的層級,請在設定產生器時,將 EnableUserCodeException
屬性設定為 "true":
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(builder => {}, options =>
{
options.EnableUserCodeException = true;
})
.Build();
host.Run();
Application Insights
您可以設定隔離式處理序應用程式,直接向 Application Insights 發出記錄。 此行為會取代透過主機轉寄記錄的預設行為。 除非您使用 .NET Aspire,否則建議您設定直接 Application Insights 整合,因為它可讓您控制這些記錄的發出方式。
在所有安裝體驗中,預設不會啟用ApplicationInsights整合。 有些範本會建立 Functions 專案,其中包含已批注的必要套件和啟動程式代碼。如果您想要使用 Application Insights 整合,您可以在 和項目的 .csproj
檔案中Program.cs
取消批注這幾行。 本節其餘部分的指示也會說明如何啟用整合。
如果您的專案是 .NET Aspire 協調流程的一部分,它會改用 OpenTelemetry 進行監視。 您不應該在 .NET Aspire 專案中啟用直接 Application Insights 整合。 請改為將 Azure 監視器 OpenTelemetry 匯出工具設定為服務預設值專案的一部分。 如果您的 Functions 專案在 .NET Aspire 內容中使用 Application Insights 整合,應用程式會在啟動時發生錯誤。
安裝套件
若要從程式碼直接將記錄寫入 Application Insights,請在專案中新增這些套件的參考:
- Microsoft.Azure.Functions.Worker.ApplicationInsights 1.0.0 版或更新版本。
- Microsoft.ApplicationInsights.WorkerService。
您可以執行下列命令,將這些參考新增至您的專案:
dotnet add package Microsoft.ApplicationInsights.WorkerService
dotnet add package Microsoft.Azure.Functions.Worker.ApplicationInsights
設定啟動
安裝套件之後,您必須在 Program.cs
檔案中的服務設定期間呼叫 AddApplicationInsightsTelemetryWorkerService()
和 ConfigureFunctionsApplicationInsights()
,如下列範例所示:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(services => {
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
})
.Build();
host.Run();
ConfigureFunctionsApplicationInsights()
的呼叫會加入 ITelemetryModule
,用於接聽函式定義的 ActivitySource
。 這會建立支援分散式追蹤所需的相依性遙測。 若要深入了解 AddApplicationInsightsTelemetryWorkerService()
和其使用方式,請參閱適用於背景工作服務應用程式的 Application Insights。
管理記錄層級
重要
Functions 主機和隔離式處理序背景工作具有個別的記錄層級設定和其他設定。host.json 中的任何 Application Insights 設定都不會影響背景工作的記錄,同樣地,在背景工作程式碼中所做的設定也不會影響主機的記錄。 如果您的案例需要在這兩個層級上進行自訂,則必須在這兩個位置上套用變更。
應用程式的其餘部分會繼續使用 ILogger
和 ILogger<T>
。 不過,根據預設,Application Insights SDK 會新增記錄篩選,以指示記錄器只擷取警告和較嚴重的記錄。 如果您想要停用此行為,請在服務設定過程中移除篩選規則:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(services => {
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
})
.ConfigureLogging(logging =>
{
logging.Services.Configure<LoggerFilterOptions>(options =>
{
LoggerFilterRule defaultRule = options.Rules.FirstOrDefault(rule => rule.ProviderName
== "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
if (defaultRule is not null)
{
options.Rules.Remove(defaultRule);
}
});
})
.Build();
host.Run();
效能最佳化
本節概述您可以啟用以改善冷啟動效能的選項。
一般而言,您的應用程式應該會使用其核心相依性的最新版本。 您至少應該更新專案,如下所示:
- 將 Microsoft.Azure.Functions.Worker 升級至 1.19.0 版或更新版本。
- 將 Microsoft.Azure.Functions.Worker.Sdk 升級至 1.16.4 版或更新版本。
- 除非您的應用程式以 .NET Framework 為目標,否則請將架構參考新增至
Microsoft.AspNetCore.App
。
下列程式碼片段會在專案檔的內容中顯示此設定:
<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.16.4" />
</ItemGroup>
預留位置
預留位置是一種平台功能,可針對以 .NET 6 或更新版本為目標的應用程式改善冷啟動。 若要使用此最佳化功能,您必須使用下列步驟明確啟用預留位置:
更新專案設定以使用最新的相依性版本,如上一節所述。
將
WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED
應用程式設定設為1
,您可以使用此 az functionapp config appsettings set 命令來執行此動作:az functionapp config appsettings set -g <groupName> -n <appName> --settings 'WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED=1'
在此範例中,將
<groupName>
取代為資源群組的名稱,並將<appName>
取代為函數應用程式的名稱。請確定函數應用程式的
netFrameworkVersion
屬性符合您專案的目標架構,其必須是 .NET 6 或更新版本。 您可以使用此 az functionapp config set 命令來執行此動作:az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>
在此範例中,也請根據您的目標 .NET 版本,將
<framework>
取代為適當的版本字串,例如v8.0
。請確定您的函數應用程式已設定為使用 64 位元處理序,您可以使用此 az functionapp config set 命令來執行此動作:
az functionapp config set -g <groupName> -n <appName> --use-32bit-worker-process false
重要
將 WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED
設定為 1
時,必須正確設定所有其他函數應用程式設定。 否則,您的函數應用程式可能無法啟動。
最佳化執行程式
函式執行程式是促使叫用執行的平台元件。 從 SDK 1.16.2 版開始,預設會啟用此元件的最佳化版本。 不需要其他設定。
ReadyToRun
您可以將函數應用程式編譯為 ReadyToRun 二進位檔。 ReadyToRun 是一種預先編譯形式,可改善啟動效能,以協助降低當在使用情況方案中執行時冷啟動的影響。 ReadyToRun 可在 .NET 6 和更新版本中使用,且需要 Azure Functions 執行階段 4.0 版或更新版本。
ReadyToRun 會要求您針對裝載應用程式的執行階段架構建置專案。 如果這些未符合,您的應用程式會在啟動時發生錯誤。 從此資料表中選取您的執行階段識別碼:
作業系統 | 應用程式是 32 位元1 | 執行階段識別碼 |
---|---|---|
Windows | True | win-x86 |
Windows | False | win-x64 |
Linux | True | N/A (不支援) |
Linux | False | linux-x64 |
1 只有 64 位元應用程式才能進行其他某些效能最佳化。
若要檢查您的 Windows 應用程式是 32 位元或 64 位元,您可以執行下列 CLI 命令,並以您的資源群組名稱取代 <group_name>
,以及以您的應用程式名稱取代 <app_name>
。 輸出 “true” 表示應用程式是 32 位元,而 “false” 則表示是 64 位元。
az functionapp config show -g <group_name> -n <app_name> --query "use32BitWorkerProcess"
您可以使用下列命令,以相同的替代內容將應用程式變更為 64 位元:
az functionapp config set -g <group_name> -n <app_name> --use-32bit-worker-process false`
若要將專案編譯為 ReadyToRun,請新增 <PublishReadyToRun>
與 <RuntimeIdentifier>
元素來更新專案檔。 下列範例示範發佈至 Windows 64 位元函數應用程式的設定。
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
如果您不想將 <RuntimeIdentifier>
設定為設定檔的一部分,您也可以將其設定為發佈動作本身的一部分。 例如,使用 Windows 64 位元函數應用程式時,.NET CLI 命令會是:
dotnet publish --runtime win-x64
在 Visual Studio 中,發行設定檔中的 [目標執行階段] 選項應該設定為正確的執行階段識別碼。 當設定為預設值 [可攜] 時,就不會使用 ReadyToRun。
部署至 Azure Functions
將函式程式碼專案部署至 Azure 時,必須在函數應用程式或 Linux 容器中執行。 函數應用程式和其他必要的 Azure 資源必須存在,您才能部署程式碼。
您也可以在 Linux 容器中部署函數應用程式。 如需詳細資訊,請參閱使用容器和 Azure Functions。
建立 Azure 資源
您可以使用下列其中一種方法,在 Azure 中建立函數應用程式和其他必要資源:
- Visual Studio:Visual Studio 可以在程式碼發佈程序期間為您建立資源。
- Visual Studio Code:Visual Studio Code 可以連線到您的訂用帳戶、建立應用程式所需的資源,然後發佈您的程式碼。
- Azure CLI:您可以使用 Azure CLI 在 Azure 中建立必要的資源。
- Azure PowerShell:您可以使用 Azure PowerShell 在 Azure 中建立必要的資源。
- 部署範本:您可以使用 ARM 範本和 Bicep 檔案,將必要資源的自動部署至 Azure。 請確定您的範本包含任何必要的設定。
- Azure 入口網站:您可以在 Azure 入口網站中建立必要的資源。
發佈您的應用程式
在 Azure 中建立函數應用程式和其他必要資源之後,您可以使用下列其中一種方法,將程式碼專案部署至 Azure:
- Visual Studio:在開發期間進行簡單的手動部署。
- Visual Studio Code:在開發期間進行簡單的手動部署。
- Azure Functions Core Tools:從命令列部署專案檔。
- 持續部署:適用於進行中的維護,經常用於預備位置。
- 部署範本:您可以使用 ARM 範本或 Bicep 檔案來自動化套件部署。
如需詳細資訊,請參閱 Azure Functions 中的部署技術。
部署承載
許多部署方法都會使用 zip 封存。 如果您要自行建立 zip 封存,它必須遵循本節中所述的結構。 如果沒有,您的應用程式可能會在啟動時遇到錯誤。
部署承載應該符合 dotnet publish
命令的輸出,不過沒有封閉的父資料夾。 zip 封存應該從下列檔案建立:
.azurefunctions/
extensions.json
functions.metadata
host.json
worker.config.json
- 您的專案可執行檔 (主控台應用程式)
- 與該可執行檔對等的其他支援檔案和目錄
這些檔案是由建置程式所產生,而且不會直接編輯。
準備 zip 封存以供部署時,您應該只壓縮輸出目錄的內容,而不是封閉目錄本身。 將封存擷取到目前的工作目錄中時,必須立即顯示上述檔案。
部署需求
根據作業系統的不同,在 Azure 中的隔離式背景工作模型中執行 .NET 函式有幾個需求:
- FUNCTIONS_WORKER_RUNTIME 的值必須設定為
dotnet-isolated
。 - netFrameworkVersion 必須設定為所需的版本。
當您使用上一節中的方法在 Azure 中建立函數應用程式時,系統會為您新增這些必要的設定。 當您使用 ARM 範本或 Bicep 檔案進行自動化,以建立這些資源時,請務必在範本中設定這些資源。
.NET Aspire (預覽)
.NET Aspire 是一個有意見的堆棧,可簡化雲端中分散式應用程式的開發。 您可以使用預覽支援,在 Aspire 9.0 協調流程中登記 .NET 8 和 .NET 9 隔離的背景工作模型專案。 本節概述登記的核心需求。
此整合需要特定的設定:
- 使用 Aspire 9.0 或更新版本 和 .NET 9 SDK。 Aspire 9.0 支援 .NET 8 和 .NET 9 架構。
- 如果您使用 Visual Studio,請更新至 17.12 版或更新版本。 您也必須擁有最新版的 Visual Studio Functions 工具。 若要檢查更新,請流覽至 [工具>選項],選擇 [項目和解決方案] 下的 [Azure Functions]。 選取 [檢查更新],並依提示安裝更新。
- 在 Aspire 應用程式主機項目中:
- 您必須參考 Aspire.Hosting.Azure.Functions。
- 您必須有 Functions 專案的項目參考。
- 在應用程式主機的 中
Program.cs
,您也必須在 上IDistributedApplicationBuilder
呼叫AddAzureFunctionsProject<TProject>()
來包含專案。 這個方法會用來取代AddProject<TProject>()
您用於其他項目類型的 。 如果您只使用AddProject<TProject>()
,Functions 專案將不會正確啟動。
- 在 Functions 專案中:
- 您必須參考 Microsoft.Azure.Functions.Worker 和 Microsoft.Azure.Functions.Worker.Sdk 的 2.x 版本。 您也必須更新對
Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore
2.x 版本的任何參考。 - 您應該
Program.cs
使用IHostApplicationBuilder
主機實例啟動的版本。 - 如果您想要使用 Aspire 服務預設值,您應該包含服務預設值項目的項目參考。 在 中
Program.cs
建置之前IHostApplicationBuilder
,您也應該包含 對builder.AddServiceDefaults()
的呼叫。 - 除了設定之外
FUNCTIONS_WORKER_RUNTIME
,您不應該將組態保留在 中local.settings.json
,這應該保持「dotnet 隔離」。 其他設定應該透過應用程式主機項目進行設定。 - 您應該移除任何直接的 Application Insights 整合。 相反地,Aspire 中的監視會透過其OpenTelemetry支援來處理。
- 您必須參考 Microsoft.Azure.Functions.Worker 和 Microsoft.Azure.Functions.Worker.Sdk 的 2.x 版本。 您也必須更新對
下列範例顯示應用程式主機專案的最小 Program.cs
專案:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject");
builder.Build().Run();
下列範例顯示 Aspire 中使用的 Functions 專案最少 Program.cs
:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = FunctionsApplication.CreateBuilder(args);
builder.AddServiceDefaults();
builder.ConfigureFunctionsWebApplication();
builder.Build().Run();
這不包括您在本文許多其他 Program.cs
範例中看到的預設 Application Insights 組態。 相反地,Aspire 的 OpenTelemetry 整合會透過 builder.AddServiceDefaults()
呼叫進行設定。
.NET Aspire 整合的考慮和最佳做法
使用 Azure Functions 評估 .NET Aspire 時,請考慮下列幾點:
- Azure Functions 與 .NET Aspire 的支援目前為預覽狀態。 在預覽期間,當您將 Aspire 解決方案發布至 Azure 時,Functions 專案會部署為 Azure Container Apps 資源,而不需要事件驅動調整。 此模式中部署的應用程式無法使用 Azure Functions 支援。
- 透過 Aspire 的觸發程式和系結組態目前僅限於特定整合。 如需詳細資訊,請參閱 使用 Aspire 的連線設定。
- 您應該
Program.cs
使用IHostApplicationBuilder
主機實例啟動的版本。 這可讓您呼叫builder.AddServiceDefaults()
將 .NET Aspire 服務預設新增至 Functions 專案。 - Aspire 使用 OpenTelemetry 進行監視。 您可以設定 Aspire 透過服務預設值項目將遙測匯出至 Azure 監視器。 在許多其他 Azure Functions 內容中,您可以註冊遙測背景工作角色服務,以包含與 Application Insights 的直接整合。 在 Aspire 中不建議這麼做,而且可能會導致 2.22.0 版的
Microsoft.ApplicationInsights.WorkerService
運行時間錯誤。 使用 Aspire 時,您應該從 Functions 專案中移除任何直接的 Application Insights 整合。 - 對於登記至 Aspire 協調流程的 Functions 專案,大部分的應用程式組態都應該來自 Aspire 應用程式主專案。 您通常應該避免在 中
local.settings.json
設定 以外的FUNCTIONS_WORKER_RUNTIME
專案。 如果 相同的環境變數是由local.settings.json
和 Aspire 設定,則系統會使用 Aspire 版本。 - 請勿針對中的任何
local.settings.json
連線設定記憶體模擬器。 許多 Functions 入門範本都包含模擬器作為的AzureWebJobsStorage
預設值。 不過,模擬器組態可能會提示某些 IDE 啟動與 Aspire 所使用的版本衝突的模擬器版本。
使用 Aspire 的聯機組態
Azure Functions 需要主機記憶體連線 (AzureWebJobsStorage
) 來進行數個核心行為。 當您在應用程式主專案中呼叫 AddAzureFunctionsProject<TProject>()
時,會建立默認 AzureWebJobsStorage
連線,並提供給 Functions 專案。 此預設聯機會使用記憶體模擬器來執行本機開發,並在部署時自動布建記憶體帳戶。 如需其他控件,您可以在 Functions 專案資源上呼叫 .WithHostStorage()
來取代此連線。
下列範例顯示取代主機記憶體之應用程式主機專案的最小 Program.cs
專案:
var builder = DistributedApplication.CreateBuilder(args);
var myHostStorage = builder.AddAzureStorage("myHostStorage");
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
.WithHostStorage(myHostStorage);
builder.Build().Run();
注意
當 Aspire 以發布模式布建主機記憶體時,預設會建立記憶體帳戶參與者、記憶體 Blob 數據參與者、記憶體佇列數據參與者和記憶體數據表數據參與者角色的角色指派。
您的觸發程式和系結會依名稱參考連線。 某些 Aspire 整合可透過對專案資源的呼叫 WithReference()
來提供這些專案:
Aspire 整合 | 備註 |
---|---|
Azure Blob | 當 Aspire 布建資源時,預設會建立記憶體 Blob 數據參與者、記憶體佇列數據參與者和記憶體數據表數據參與者角色的角色指派。 |
Azure 佇列 | 當 Aspire 布建資源時,預設會建立記憶體 Blob 數據參與者、記憶體佇列數據參與者和記憶體數據表數據參與者角色的角色指派。 |
Azure 事件中樞 | 當 Aspire 佈建資源時,預設會使用 Azure 事件中樞 數據擁有者角色來建立角色指派。 |
Azure 服務匯流排 | 當 Aspire 佈建資源時,預設會使用 Azure 服務匯流排 數據擁有者角色建立角色指派。 |
下列範例顯示設定佇列觸發程式之應用程式主機專案的最小 Program.cs
專案。 在此範例中,對應的佇列觸發程式其 Connection
屬性已設定為 “MyQueueTriggerConnection”。
var builder = DistributedApplication.CreateBuilder(args);
var myAppStorage = builder.AddAzureStorage("myAppStorage").RunAsEmulator();
var queues = myAppStorage.AddQueues("queues");
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
.WithReference(queues, "MyQueueTriggerConnection");
builder.Build().Run();
對於其他整合,呼叫 WithReference
以不同的方式設定組態,使其可供 Aspire 用戶端整合使用,但無法觸發和系結。 針對這些整合,您應該呼叫 WithEnvironment()
以傳遞觸發程式或系結的連線資訊來解析。 下列範例示範如何為公開 連接字串 表達式的資源設定環境變數 “MyBindingConnection” :
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
.WithEnvironment("MyBindingConnection", otherIntegration.Resource.ConnectionStringExpression);
如果您要 Aspire 用戶端整合和觸發程式和繫結系統同時使用連線,您可以同時 WithReference()
設定 和 WithEnvironment()
。
針對某些資源,當您在本機執行連線和將連線發佈至 Azure 時,連線的結構可能會有所不同。 在上述範例中,otherIntegration
可能是以模擬器身分執行的資源,因此ConnectionStringExpression
會傳回模擬器 連接字串。 不過,發佈資源時,Aspire 可能會設定身分識別型連線,並 ConnectionStringExpression
傳回服務的 URI。 在此情況下,若要設定 Azure Functions 的身分識別型連線,您可能需要提供不同的環境變數名稱。 下列範例會使用 builder.ExecutionContext.IsPublishMode
來有條件地新增必要的後綴:
builder.AddAzureFunctionsProject<Projects.MyFunctionsProject>("MyFunctionsProject")
.WithEnvironment("MyBindingConnection" + (builder.ExecutionContext.IsPublishMode ? "__serviceUri" : ""), otherIntegration.Resource.ConnectionStringExpression);
視您的案例而定,您可能也需要調整指派給身分識別型連線的許可權。 您可以使用 ConfigureConstruct<T>()
方法來 自訂 Aspire 在發佈專案時如何設定基礎結構。
如需所支援連接格式的詳細數據,以及這些格式所需的許可權,請參閱每個系結的 參考頁面 。
偵錯
使用 Visual Studio 或 Visual Studio Code 在本機執行時,您可以正常偵錯 .NET 隔離式背景工作專案。 不過,有兩個偵錯案例無法如預期般運作。
使用 Visual Studio 遠端偵錯
因為隔離式背景工作處理序應用程式會在 Functions 執行階段之外執行,所以您必須將遠端偵錯工具連結至個別處理序。 若要深入瞭解如何使用 Visual Studio 進行偵錯,請參閱遠端偵錯。
以 .NET Framework 為目標時進行偵錯
如果您的隔離專案以 .NET Framework 4.8 為目標,您必須採取手動步驟來啟用偵錯。 這些步驟在使用另一個目標架構時為非必要。
您的應用程式應該從呼叫 FunctionsDebugger.Enable();
作為其第一個作業開始。 在初始化 HostBuilder 之前,會在 Main()
方法中發生此情況。 您的 Program.cs
檔案應類似於下方所示:
using System;
using System.Diagnostics;
using Microsoft.Extensions.Hosting;
using Microsoft.Azure.Functions.Worker;
using NetFxWorker;
namespace MyDotnetFrameworkProject
{
internal class Program
{
static void Main(string[] args)
{
FunctionsDebugger.Enable();
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.Build();
host.Run();
}
}
}
接下來,您必須使用 .NET Framework 偵錯工具手動附加至處理程序。 Visual Studio 尚未針對隔離式背景工作處理序 .NET Framework 應用程式自動執行此操作,且應該避免「開始偵錯」作業。
在您的專案目錄中 (或其建置輸出目錄) 中,執行:
func host start --dotnet-isolated-debug
這會啟動您的背景工作,且處理序會停止並顯示下列訊息:
Azure Functions .NET Worker (PID: <process id>) initialized in debug mode. Waiting for debugger to attach...
其中 <process id>
是背景工作處理序的識別碼。 您現在可以使用 Visual Studio 手動附加至處理程序。 如需此作業的指示,請參閱如何附加至執行中的處理程序。
連結偵錯工具之後,處理序執行將會繼續,且您將能夠進行偵錯。
預覽 .NET 版本
在正式發行之前,.NET 版本可能會以預覽或上線狀態發行。 如需這些狀態的詳細資訊,請參閱 .NET 官方支援原則。
雖然能夠以本機 Functions 專案中的指定版本為目標,但裝載在 Azure 中的函數應用程式可能無法使用該版本。 Azure Functions 只能與本節所述的預覽或上線版本搭配使用。
Azure Functions 目前不適用於任何「預覽」或「上線」.NET 版本。 如需可使用的正式推出版本清單,請參閱支援的版本。
使用預覽 .NET SDK
若要搭配 .NET 的預覽版本使用 Azure Functions,您必須透過下列方式更新專案:
- 在您的開發中安裝相關的 .NET SDK 版本
- 變更
.csproj
檔案中的TargetFramework
設定
在部署至 Azure 中的函數應用程式時,也需要確保架構可供應用程式使用。 在預覽期間,某些工具和體驗可能不會將新的預覽版本顯示為選項。 例如,如果您沒有看到 Azure 入口網站 中包含的預覽版本,您可以使用 REST API、Bicep 範本或 Azure CLI 手動設定版本。
針對託管到 Windows 的應用程式,請使用下列 Azure CLI 命令。 此外,請將 <groupName>
取代為資源群組的名稱,並將 <appName>
取代為函數應用程式的名稱。 將 <framework>
取代為適當的版本字串,例如 v8.0
。
az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>
使用 .NET 預覽版本的考量
在搭配 .NET 預覽版本使用 Functions 時,請記住這些考量:
當您在 Visual Studio 中撰寫函式時,必須使用 Visual Studio Preview,其支援使用 .NET 預覽 SDK 建置 Azure Functions 專案。
請確定您有最新的 Functions 工具和範本。 若要更新您的工具:
- 瀏覽至 [工具]>[選項],選擇 [專案和解決方案] 底下的 [Azure Functions]。
- 選取 [檢查更新],並依提示安裝更新。
在預覽期間,您開發環境具有的 .NET 預覽版本可能會比託管服務還新。 這可能會導致函數應用程式在部署時失敗。 若要解決此問題,您可以指定要在
global.json
中使用的 SDK 版本。- 執行
dotnet --list-sdks
命令,並記下您在本機開發期間使用的預覽版本。 - 執行
dotnet new globaljson --sdk-version <SDK_VERSION> --force
命令,其中<SDK_VERSION>
是您在本機使用的版本。 例如,dotnet new globaljson --sdk-version dotnet-sdk-8.0.100-preview.7.23376.3 --force
會讓系統在建置專案時使用 .NET 8 Preview 7 SDK。
- 執行
注意
由於預覽架構的 Just-In-Time 載入,在 Windows 上執行的函數應用程式可能會遇到冷啟動時間增加 (相較於更早的 GA 版本)。