在隔離的背景工作模型中執行 C# Azure Functions 的指南

本文是使用隔離背景工作模型在 .NET 中使用 Azure Functions 的簡介。 此模型可讓您的專案以與其他運行時間元件無關的 .NET 版本為目標。 如需所支援特定 .NET 版本的相關信息,請參閱 支援的版本

使用下列連結立即開始建置 .NET 隔離的背景工作模型函式。

開始使用 概念 範例

若要深入瞭解如何將隔離的背景工作模型專案部署至 Azure,請參閱 部署至 Azure Functions

隔離背景工作模型的優點

有兩種模式可讓您執行 .NET 類別庫函式:在與 Functions 主機運行時間(同進程)相同的進程中,或在隔離的背景工作進程中執行。 當您的 .NET 函式在隔離的背景工作進程中執行時,您可以利用下列優點:

  • 衝突較少: 因為您的函式會在個別進程中執行,應用程式中使用的元件不會與主機進程所使用的相同元件不同版本發生衝突。
  • 程式的完整控制:您可以控制應用程式的啟動,這表示您可以管理所使用的設定,並啟動中間件。
  • 標準相依性插入: 因為您可以完全控制程式,因此您可以使用目前的 .NET 行為進行相依性插入,並將中間件併入函式應用程式。
  • .NET 版本彈性: 在主機進程外部執行表示您的函式可以在函式運行時間不支援的 .NET 版本上執行,包括 .NET Framework。

如果您有執行進程中的現有 C# 函式應用程式,您必須移轉應用程式以利用這些優點。 如需詳細資訊,請參閱 將 .NET 應用程式從進程內模型遷移至隔離的背景工作模型

如需這兩種模式之間的全面比較,請參閱 同進程與隔離背景工作進程 .NET Azure Functions 之間的差異。

支援的版本

Functions 執行階段的版本支援 .NET 特定版本。 若要深入瞭解 Functions 版本,請參閱 Azure Functions 執行階段版本概觀。 版本支援也取決於函式執行內含式或隔離式背景工作處理序。

注意

若要瞭解如何變更函數應用程式所使用的 Functions 執行階段版本,請參閱檢視及更新目前的執行階段版本

下表顯示可與 Functions 特定版本搭配使用的最高層級 .NET 或 .NET Framework。

Functions 執行階段版本 隔離式背景工作角色模型 進程內模型5
Functions 4.x .NET 8.0
.NET 7.01
.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 SDK4 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() 之前,您應該:

  • ConfigureFunctionsWebApplication()如果使用 ASP.NET Core 整合,則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 套件,從適用於 .NETAzure 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);
    }
}

繫結

系結是在方法、參數和傳回型別上使用屬性來定義。 系結可以提供字串、數位和可串行化類型的數據,例如一般舊的類別物件(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;
}

多個輸出系結

寫入輸出系結的數據一律是函式的傳回值。 如果您需要寫入多個輸出系結,您必須建立自定義傳回類型。 這個傳回型別必須套用至 類別的一或多個屬性的輸出系結屬性。 下列來自 HTTP 觸發程式的範例會同時寫入 HTTP 回應和佇列輸出系結:

public static class MultiOutput
{
    [Function(nameof(MultiOutput))]
    public static MyOutputType Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req,
        FunctionContext context)
    {
        var response = req.CreateResponse(HttpStatusCode.OK);
        response.WriteString("Success!");

        string myQueueOutput = "some output";

        return new MyOutputType()
        {
            Name = myQueueOutput,
            HttpResponse = response
        };
    }
}

public class MyOutputType
{
    [QueueOutput("myQueue")]
    public string Name { get; set; }

    public HttpResponseData HttpResponse { get; set; }
}

來自 HTTP 觸發程式的回應一律會被視為輸出,因此不需要傳回值屬性。

SDK 類型

對於某些服務特定的系結類型,可以使用來自服務 SDK 和架構的類型來提供系結數據。 這些提供比串行化字串或純舊 CLR 物件 (POCO) 所能提供的功能更多。 若要使用較新的類型,您的項目必須更新,才能使用較新版本的核心相依性。

相依性 版本需求
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、HttpResponseIActionResult。 此模型不適用於 以 .NET Framework 為目標的應用程式,而應該改用 內建模型

注意

並非所有 ASP.NET Core 的功能都會由此模型公開。 具體而言,ASP.NET 核心中間件管線和路由功能無法使用。 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

下列範例示範 和 HttpResponseData的使用HttpRequestData

[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 實例寫入記錄ILogger<T>。 記錄器可以透過 ILoggerFactory 的相依性插入ILogger<T>來取得:

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 方法來ILogger<T>寫入各種紀錄層級,例如 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_DOTNETISOLATED1時,必須正確設定所有其他函式應用程式組態。 否則,您的函式應用程式可能無法啟動。

優化執行程式

函式執行程式是導致調用執行之平臺的元件。 從 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 中建立函式應用程式和其他必要資源:

發佈程式代碼專案

在 Azure 中建立函式應用程式和其他必要資源之後,您可以使用下列其中一種方法,將程式代碼專案部署至 Azure:

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

部署需求

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

  • FUNCTIONS_WORKER_RUNTIME必須設定為的值dotnet-isolated
  • netFrameworkVersion 必須設定為所需的版本。

當您使用上一節中的方法在 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 版本可能會以 預覽Go-live 狀態發行。 如需這些狀態的詳細資訊, 請參閱 .NET 官方支持原則

雖然可能以本機 Functions 專案中的指定版本為目標,但裝載在 Azure 中的函式應用程式可能無法使用該版本。 Azure Functions 只能與本節所述的預覽或 Go-live 版本搭配使用。

Azure Functions 目前不適用於任何「預覽」或「Go-live」.NET 版本。 如需您可以使用的一般可用版本清單,請參閱 支援的版本

使用預覽 .NET SDK

若要搭配使用 Azure Functions 與 .NET 的預覽版本,您必須透過下列方式更新專案:

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

在 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.jsonSDK 版本。

    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 時,可能會體驗到冷啟動時間增加。

下一步