共用方式為


在隔離的背景工作模型中執行 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 執行階段版本 隔離式背景工作模型 進程內模型5
Functions 4.x1 .NET 8.0
.NET 6.02
.NET Framework 4.83
.NET 6.02
Functions 1.x4 n/a .NET Framework 4.8

1.NET 7 先前在隔離的工作者模型上受到支援,但於 2024 年 5 月 14 日終止 正式支援

2 .NET 6 於 2024 年 11 月 12 日結束正式支援

3 建置程式也需要 .NET SDK

4 1.x 版的 Azure Functions 執行階段於 2026 年 9 月 14 日結束支援。 如需詳細資訊,請參閱此支援公告。 如需持續的完整支援,您應該將應用程式移轉至 4.x 版

5 支援會在 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 函式:

延伸模組套件

因為 .NET 隔離式背景工作處理序會使用不同的繫結類型,所以其需要一組唯一的繫結延伸模組套件。

您可以在 Microsoft.Azure.Functions.Worker.Extensions 底下找到這些延伸模組套件。

啟動和設定

使用 .NET 隔離式函式時,您可以存取函數應用程式的啟動,這通常位於 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;

HostBuilder 上呼叫 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 中的設定

這些設定適用於在個別處理程序中執行的函數應用程式。 若要變更函式主機或觸發程序以及繫結設定,您仍然需要使用 host.json 檔案

注意

自定義組態來源無法用於設定觸發程式和系結。 觸發程式和系結組態必須可供 Functions 平臺使用,而不只是您的應用程式程式代碼。 您可以透過應用程式設定金鑰保存庫 參考或 應用程式組態 參考功能來提供此組態。

相依性插入

相較於必須建立啟動類別來註冊服務的 .NET 同處理序函式,相依性插入已簡化。

針對 .NET 隔離式處理序應用程式,您可以在主機產生器上使用 .NET 標準方法來呼叫 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.Extensions.Azure;
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 中定義。

中介軟體

.NET 隔離式也支援中介軟體註冊,同樣地,使用類似於 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 一部分,以自定義串行化程序的行為。 下列範例示範如何使用 ConfigureFunctionsWebApplication,但它也適用於 ConfigureFunctionsWorkerDefaults

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();

您可能想要改用 JSON.NET (Newtonsoft.Json) 進行串行化。 若要這樣做,您會安裝 Microsoft.Azure.Core.NewtonsoftJson 套件。 然後,在服務註冊中,您會在設定上WorkerOptions重新指派 Serializer 屬性。 下列範例示範如何使用 ConfigureFunctionsWebApplication,但它也適用於 ConfigureFunctionsWorkerDefaults

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();

辨識為函式的方法

函式方法是公用類別的公用方法,方法會套用 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.ToString()}"};

    _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] 屬性新增至提供結果的屬性。 HttpResult使用 SDK 1.17.3-preview2 或更新版本以及 3.2.0 版或更新版本的 HTTP 擴充功能和 1.3.0 版或更新版本 ASP.NET 時,可以使用 屬性。

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 要求和回應物件,包括 HttpRequestHttpResponseIActionResult。 此模型不適用於以 .NET Framework 為目標的應用程式,其應該改用內建模型

注意

並非所有 ASP.NET Core 的功能都會由此模型公開。 具體而言,ASP.NET Core 中介軟體管線和路由功能都無法使用。 ASP.NET Core 整合需要您使用更新的套件。

若要啟用 HTTP 的 ASP.NET Core 整合:

  1. 將專案中的參考新增至 Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore 套件 1.0.0 版或更新版本。

  2. 更新您的專案以使用這些特定的套件版本:

  3. 在您的 Program.cs 檔案中,更新主機產生器設定以使用 ConfigureFunctionsWebApplication(),而不是使用 ConfigureFunctionsWorkerDefaults()。 下列範例顯示不含其他自訂的最低限度設定:

    using Microsoft.Extensions.Hosting;
    using Microsoft.Azure.Functions.Worker;
    
    var host = new HostBuilder()
        .ConfigureFunctionsWebApplication()
        .Build();
    
    host.Run();
    
  4. 更新任何現有的 HTTP 觸發程序函數,以使用 ASP.NET Core 類型。 此範例顯示用於簡單 "hello, world" 函式的標準 HttpRequestIActionResult

    [Function("HttpFunction")]
    public IActionResult Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req)
    {
        return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!");
    }
    

內建 HTTP 模型

在內建模型中,系統會將傳入的 HTTP 要求訊息轉譯成傳遞至函式的 HttpRequestData 物件。 這個物件會提供來自要求的資料,包括 HeadersCookiesIdentitiesURL 和選擇性訊息 Body。 此物件是 HTTP 要求的表示法,但不會直接連線到基礎 HTTP 接聽程式或接收的訊息。

同樣地,函式會傳回 HttpResponseData 物件,該物件會提供用來建立 HTTP 回應的資料,包括訊息 StatusCodeHeaders 和選擇性的訊息 Body

下列範例示範 HttpRequestDataHttpResponseData 的用法:

[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;
}

記錄

在 .NET 隔離式處理序中,您可以使用 ILogger<T>ILogger 執行個體寫入記錄。 記錄器可以透過 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 方法來寫入各種記錄層級,例如 LogWarningLogError。 若要深入瞭解記錄層級,請參閱監視文章。 您可以藉由將篩選條件註冊為 HostBuilder 設定的一部分,來自訂新增至程式碼的元件記錄層級:

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 中設定應用程式時,您也可以定義錯誤如何在記錄中呈現的行為。 根據預設,程式碼擲回的例外狀況最後會包裝在 RpcException 中。 若要移除這個額外的層級,請在設定產生器時,將 EnableUserCodeException 屬性設定為 "true":

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(builder => {}, options =>
    {
        options.EnableUserCodeException = true;
    })
    .Build();

Application Insights

您可以設定隔離的進程應用程式,將記錄直接發出至 Application Insights。 此行為會取代透過主機轉送記錄的預設行為,建議使用此方式,因為您可以控制這些記錄的發出方式。

安裝套件

若要從程式碼直接將記錄寫入 Application Insights,請在專案中新增這些套件的參考:

您可以執行下列命令,將這些參考新增至您的專案:

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 設定都不會影響背景工作的記錄,同樣地,在背景工作程式碼中所做的設定也不會影響主機的記錄。 如果您的案例需要在這兩個層級上進行自訂,則必須在這兩個位置上套用變更。

應用程式的其餘部分會繼續使用 ILoggerILogger<T>。 不過,根據預設,Application Insights SDK 會新增記錄篩選,以指示記錄器只擷取警告和較嚴重的記錄。 如果您想要停用此行為,請在服務設定過程中移除篩選規則:

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();

效能最佳化

本節概述您可以啟用以改善冷啟動效能的選項。

一般而言,您的應用程式應該會使用其核心相依性的最新版本。 您至少應該更新專案,如下所示:

  1. Microsoft.Azure.Functions.Worker 升級至 1.19.0 版或更新版本。
  2. Microsoft.Azure.Functions.Worker.Sdk 升級至 1.16.4 版或更新版本。
  3. 除非您的應用程式以 .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 或更新版本為目標的應用程式改善冷啟動。 若要使用此最佳化功能,您必須使用下列步驟明確啟用預留位置:

  1. 更新專案設定以使用最新的相依性版本,如上一節所述。

  2. 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> 取代為函數應用程式的名稱。

  3. 請確定函數應用程式的 netFrameworkVersion 屬性符合您專案的目標架構,其必須是 .NET 6 或更新版本。 您可以使用此 az functionapp config set 命令來執行此動作:

    az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>
    

    在此範例中,也請根據您的目標 .NET 版本,將 <framework> 取代為適當的版本字串,例如 v8.0v7.0v6.0

  4. 請確定您的函數應用程式已設定為使用 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:

如需詳細資訊,請參閱 Azure Functions 中的部署技術

部署需求

根據作業系統的不同,在 Azure 中的隔離式背景工作模型中執行 .NET 函式有幾個需求:

當您使用上一節中的方法在 Azure 中建立函數應用程式時,系統會為您新增這些必要的設定。 當您使用 ARM 範本或 Bicep 檔案進行自動化,以建立這些資源時,請務必在範本中設定這些資源。

偵錯

使用 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,您必須透過下列方式更新專案:

  1. 在您的開發中安裝相關的 .NET SDK 版本
  2. 變更 .csproj 檔案中的 TargetFramework 設定

部署至 Azure 中的函數應用程式時,您也需要確保架構可供應用程式使用。 若要在 Windows 上這樣做,您可以使用下列 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 工具和範本。 若要更新您的工具:

    1. 瀏覽至 [工具]>[選項],選擇 [專案和解決方案] 底下的 [Azure Functions]
    2. 選取 [檢查更新],並依提示安裝更新。
  • 在預覽期間,您開發環境具有的 .NET 預覽版本可能會比託管服務還新。 這可能會導致函數應用程式在部署時失敗。 若要解決此問題,您可以指定要在 global.json 中使用的 SDK 版本。

    1. 執行 dotnet --list-sdks 命令,並記下您在本機開發期間使用的預覽版本。
    2. 執行 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 版本)。

下一步