共用方式為


在隔離式背景工作模型中執行 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
函數 4.x1 .NET 9.0
.NET 8.0
.NET Framework 4.82
.NET 8.0
函數 1.x3 n/a .NET Framework 4.8

1.NET 6 以前在兩種型號上都受到支援,但已於 2024 年 11 月 12 日終止官方支援 。 .NET 7 先前在隔離式背景工作角色模型上受到支援,但於 2024 年 5 月 14 日終止正式支援。

2 建置程式也需要 .NET SDK

3 Azure Functions 運行時間 1.x 版的支援將於 2026 年 9 月 14 日結束。 如需詳細資訊,請參閱此支援公告。 如需持續的完整支援,您應該將應用程式移轉至 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 包含安裝 dotnet run 時, 的支援 。 在 Windows 上,核心工具必須透過 NPM 以外的機制來安裝。
  • Microsoft.Azure.Functions.Worker 的 2.0.0 版開始:
    • 此版本新增 對 IHostApplicationBuilder的支援。 本指南中的一些範例包含使用 IHostApplicationBuilder 的索引標籤來顯示替代方案。 這些範例需要 2.x 版本。
    • 在開發環境中執行時,預設會包含服務提供者範圍驗證。 此行為符合 Core ASP.NET。
    • 此選項 EnableUserCodeException 預設為啟用。 屬性現在標示為過時。
    • 此選項 IncludeEmptyEntriesInMessagePayload 預設為啟用。 啟用此選項後,代表集合的觸發負載一律包含空的條目。 例如,如果訊息在沒有主體的情況下傳送,則在string[]中的觸發數據仍會顯示一個空白項目。 包含空條目有助於與函式可能會參考的元數據陣列進行交叉引用。 在服務組態中,您可以將 IncludeEmptyEntriesInMessagePayload 設定為 false 來停用此行為。
    • 類別 ILoggerExtensions 會重新命名為 FunctionsLoggerExtensions。 重新命名可防止在LogMetric()實例上使用ILogger時發生模棱兩可的呼叫錯誤。
    • 對於使用 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;

Build() 上呼叫 IHostBuilder 之前,您應該:

  • 如果使用 ConfigureFunctionsWebApplication(),則呼叫 ,否則呼叫 ConfigureFunctionsWorkerDefaults()。 如需這些選項的詳細資訊,請參閱 HTTP 觸發程序
    如果您要使用 F# 撰寫應用程式,則某些觸發程序和繫結延伸模組需要額外設定。 當您打算在 F# 應用程式中使用延伸模組時,請參閱 Blob 延伸模組資料表延伸模組Cosmos DB 延伸模組的設定文件。
  • 設定專案所需的任何服務或應用程式設定。 如需詳細資訊,請參閱設定
    如果您打算使用 Application Insights,必須在 AddApplicationInsightsTelemetryWorkerService() 委派函式中呼叫 ConfigureFunctionsApplicationInsights()ConfigureServices()。 如需詳細資訊,請參閱 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 插入用戶端。 安裝套件之後,請在 中的服務集合上呼叫 AddAzureClients()Program.cs。 下列範例會設定 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 套件。 然後,在服務註冊中,您會在 Serializer 組態上重新指派 WorkerOptions 屬性。 下列範例示範如何使用 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 Isolated 函式會將 FunctionContext 物件傳遞至你的函式方法。 此物件可讓您藉由呼叫 ILogger 方法並提供 字串,取得 categoryName 執行個體以寫入記錄。 您可以使用此內容來取得 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);
    }
}

導致取消的案例

取消函式叫用時,會發出取消權杖的訊號。 有數個原因可能會導致取消,而這些原因可能會因所使用的觸發程序類型而有所不同。 一些常見的原因如下:

  1. 用戶端中斷連線:叫用函式的用戶端已中斷連線。 這最有可能適用於 HttpTrigger 函式。
  2. 函數應用程式重新啟動:如果您 (或平台) 重新啟動 (或停止) 函數應用程式,則會在幾乎相同時間要求叫用。 重新啟動可能會因為背景工作角色執行個體移動、背景工作角色執行個體更新或擴充而發生。
    • 重新啟動事件期間的叫用正式發行前小眾測試版可能會根據其觸發方式進行重試。 如需詳細資訊,請參閱 重試檔

針對隔離的背景工作角色模型,即使在主機能夠將叫用要求傳送給背景工作角色之前將取消權杖取消,我們還是會將叫用傳送給背景工作角色。

如果您不想將預先取消的叫用傳送給背景工作角色,可以將 SendCanceledInvocationsToWorker 屬性新增至 host.json 檔案,以停用此行為。 下列範例顯示使用這個屬性的 host.json 檔案:

{
    "version": "2.0",
    "SendCanceledInvocationsToWorker": "false"
}

重要

SendCanceledInvocationsToWorker 設定為 false 可能會導致 FunctionInvocationCanceled 例外狀況,並出現下列記錄:

Cancellation has been requested. The invocation request with id '{invocationId}' is canceled and will not be sent to the worker

當主機已將傳入叫用要求傳送給背景工作角色之前,將取消權杖 (如上述其中一個事件所導致) 取消時,就會發生這種情況。 此例外狀況可以安全地忽略,而且當SendCanceledInvocationsToWorkerfalse時是預期中的。

繫結

繫結是使用方法、參數和傳回型別的屬性來定義。 繫結能夠以字串、陣列和可序列化的型別提供資料,例如簡單的 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] 屬性新增至提供結果的屬性。 使用 HttpResult,以及 3.2.0 版或更新版本的 HTTP 延伸模組1.3.0 版或更新版本的 ASP.NET Core 延伸模組時,可以使用 屬性。

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
Azure 事件網格 正式推出 輸入繫結不存在 不建議的 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 整合需要您使用更新的套件。

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

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

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

  3. 在您的 Program.cs 檔案中,更新主機產生器組態以呼叫 ConfigureFunctionsWebApplication()。 如果您其他地方使用該方法,這會取代 ConfigureFunctionsWorkerDefaults()。 下列範例顯示不含其他自訂的最低限度設定:

    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Extensions.Hosting;
    
    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"]}!");
    }
    

使用 ASP.NET Core 整合進行 JSON 序列化

ASP.NET Core 有自己的序列化層級,且不受自訂一般序列化設定的影響。 若要自訂 HTTP 觸發程序所使用的序列化行為,您必須在服務註冊中包含 .AddMvc() 呼叫。 傳回 IMvcBuilder 可用來修改 ASP.NET Core 的 JSON 序列化設定。

雖然使用 ASP.NET 整合時您可以繼續使用 HttpRequestDataHttpResponsedata,但對於大部分的應用程式,最好改用 HttpRequestIActionResult。 使用 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 物件。 這個物件會提供來自要求的資料,包括 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;
}

記錄

您可以使用 ILogger<T>ILogger 實體寫入記錄。 記錄器可以透過 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<T>ILogger 方法來寫入各種記錄層級,例如 LogWarningLogError。 若要深入瞭解記錄層級,請參閱監視文章。 您可以藉由註冊篩選,來為新增至程式碼的元件自訂記錄層級:

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 整合功能,您可以在 Program.cs 中及項目的 .csproj 檔案中取消註解這幾行。 本節其餘部分的指示也會說明如何啟用整合。

如果您的專案是 .NET Aspire 協調流程的一部分,它會改用 OpenTelemetry 進行監視。 您不應該在 .NET Aspire 專案中啟用直接 Application Insights 整合。 請改為將 Azure 監視器 OpenTelemetry 匯出工具設定為服務預設值專案的一部分。 如果您的 Functions 專案在 .NET Aspire 內容中使用 Application Insights 整合,應用程式會在啟動時發生錯誤。

安裝套件

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

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

dotnet add package Microsoft.ApplicationInsights.WorkerService
dotnet add package Microsoft.Azure.Functions.Worker.ApplicationInsights

設定啟動

安裝套件之後,您必須在 AddApplicationInsightsTelemetryWorkerService() 檔案中的服務設定期間呼叫 ConfigureFunctionsApplicationInsights()Program.cs,如下列範例所示:

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 會新增記錄篩選,以指示記錄器只擷取警告和較嚴重的記錄。 如果您想要停用此行為,請在服務設定過程中移除篩選規則:

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

效能最佳化

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

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

  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.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 執行階段識別碼
窗戶 win-x86
窗戶 錯誤 win-x64
Linux N/A (不支援)
Linux 錯誤 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 中的部署技術

部署承載

許多部署方法都會使用 zip 封存。 如果您要自行建立 zip 封存,它必須遵循本節中所述的結構。 如果沒有,您的應用程式可能會在啟動時遇到錯誤。

部署承載應該符合 dotnet publish 命令的輸出,不過沒有封閉的父資料夾。 zip 封存應該從下列檔案建立:

  • .azurefunctions/
  • extensions.json
  • functions.metadata
  • host.json
  • worker.config.json
  • 您的專案可執行檔 (主控台應用程式)
  • 與該可執行檔對等的其他支援檔案和目錄

這些檔案是由建置程式所產生,而且不會直接編輯。

準備 zip 封存以供部署時,您應該只壓縮輸出目錄的內容,而不是封閉目錄本身。 將封存擷取到目前的工作目錄中時,必須立即顯示上述檔案。

部署需求

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

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

.NET Aspire (預覽)

.NET Aspire 是一個有意見的堆棧,可簡化雲端中分散式應用程式的開發。 您可以使用預覽支援,在 Aspire 9.0 協調流程中登錄 .NET 8 和 .NET 9 隔離的背景工作角色模型專案。 如需詳細資訊,請參閱 Azure Functions with .NET 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,您必須透過下列方式更新專案:

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

在部署至 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 工具和範本。 若要更新您的工具:

    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 版本)。

下一步