分離ワーカー プロセスにおける C# Azure Functions の実行のガイド

この記事では、Azure の分離ワーカー プロセスで関数を実行する .NET Functions 分離ワーカー プロセスの操作の概要について説明します。 これにより、Functions ホスト プロセスで使用されるバージョンとは異なるバージョンの .NET で .NET クラス ライブラリ関数を実行できます。 サポートされている特定の .NET バージョンの詳細については、「サポートされているバージョン」を参照してください。

次のリンクを使用して、.NET 分離ワーカー プロセス関数の構築をすぐに開始してください。

作業の開始 概念 サンプル

引き続きホストと同じプロセスで関数を実行する必要がある場合は、インプロセス C# クラス ライブラリ関数に関する記事を参照してください。

分離ワーカー プロセスとインプロセスの .NET 関数の包括的な比較については、「インプロセスと分離ワーカー プロセスの .NET Azure Functions の違い」を参照してください。

インプロセス モデルから分離ワーカー モデルへの移行について知るには、「.NET アプリをインプロセス モデルから分離ワーカー モデルに移行する」を参照してください。

.NET Functions 分離ワーカー プロセスを使用する理由

Azure Functions は、導入されたときには、.NET 関数の緊密に統合されたモードのみをサポートしていました。 この "インプロセス" モードでは、.NET クラス ライブラリ関数はホストと同じプロセスで実行されます。 このモードにより、ホスト プロセスと関数の間の統合が深くなります。 たとえば、.NET クラス ライブラリ関数が同じプロセスで実行されているときは、バインド API と型を共有できます。 しかし、この統合では、ホスト プロセスと .NET 関数の間の結合がより緊密になっている必要もあります。 たとえば、インプロセスで実行中の .NET 関数が Functions ランタイムと同じ .NET のバージョンで実行される必要があります。 つまり、インプロセス関数は、長期サポート (LTS) がある .NET のバージョンでのみ実行できます。 非 LTS バージョンの .NET で実行できるようにするには、代わりに分離ワーカー プロセスで実行することを選択できます。 このプロセス分離を使用すると、Functions ランタイムでネイティブにサポートされていない、現在の .NET リリース (.NET Framework を含む) を使用する関数を開発できます。 分離ワーカー プロセスとインプロセス C# クラス ライブラリ関数は、どちらも LTS バージョンで実行されます。 詳しくは、サポートされるバージョンをご覧ください。

これらの関数は別個のプロセスで実行されるため、.NET 分離関数アプリと .NET クラス ライブラリ関数アプリの間には特徴と機能の違いがいくつかあります。

分離ワーカー プロセスの利点

.NET 関数を分離ワーカー プロセスで実行すると、次のような利点を利用できます。

  • 競合が少ない: 関数は別個のプロセスで実行されるため、アプリで使用されるアセンブリは、ホスト プロセスにより使用される同じアセンブリの異なるバージョンと競合しません。
  • プロセスの完全制御: アプリの起動を制御でき、使用する構成や起動するミドルウェアを制御できます。
  • 依存関係の挿入: プロセスを完全制御できるため、現在の .NET 動作を使用して、依存関係の挿入や関数アプリへのミドルウェアの組み込みを行えます。

サポートされているバージョン

Functions ランタイムの各バージョンでは、.NET の特定のバージョンがサポートされています。 Functions のバージョンの詳細については、「Azure Functions ランタイム バージョンの概要」を参照してください。 バージョンのサポートは、関数がインプロセスで実行されるか、分離ワーカー プロセスで実行されるかによっても異なります。

Note

関数アプリで使用される Functions ランタイム バージョンを変更する方法については、「現在のランタイム バージョンの表示と更新」を参照してください。

次の表は、特定のバージョンの Functions と共に使用できる最上位レベルの .NET と .NET Framework を示しています。

Functions ランタイムのバージョン 分離ワーカー プロセス
(.NET 分離)
インプロセス
(.NET クラス ライブラリ)
Functions 4.x .NET 8.0
.NET 7.01
.NET 6.02
.NET Framework 4.83
.NET 6.02
Functions 4.x1 該当なし .NET Framework 4.8

1.NET 公式サポート ポリシーに従って、.NET 7 のサポートは 2024 年 5 月 14 日に終了します。

2.NET 公式サポート ポリシーに従って、.NET 6 のサポートは 2024 年 11 月 12 日に終了します。

3 ビルド プロセスには .NET 6 SDK も必要です。

4Azure Functions Runtime のバージョン 1.x のサポートは 2026 年 9 月 14 日に終了します。 完全なサポートのために、アプリをバージョン 4.x に移行することを強くお勧めします。

特定の古いマイナー バージョンの削除など、Azure Functions リリースに関する最新のニュースについては、Azure App Service のお知らせを閲覧してください。

.NET 分離ワーカー モデル プロジェクト

分離ワーカー モデルを使用する Azure Functions 用 .NET プロジェクトは、基本的には、サポートされる .NET ランタイムをターゲットとする .NET コンソール アプリ プロジェクトです。 以下は、.NET 分離プロジェクトで必要となる基本的なファイルです。

  • host.json ファイル
  • local.settings.json ファイル
  • プロジェクトと依存関係を定義する C# プロジェクト ファイル (.csproj)
  • アプリのエントリ ポイントである Program.cs ファイル。
  • 関数を定義するすべてのコード ファイル。

詳細な例については、.NET 8 サンプル プロジェクト.NET Framework 4.8 サンプル プロジェクトを参照してください。

Note

分離ワーカー モデルを使用して Azure の Windows または Linux 関数アプリにプロジェクトを発行できるようにするには、リモート FUNCTIONS_WORKER_RUNTIME アプリケーションの設定で dotnet-isolated の値を設定する必要があります。 zip デプロイと Linux 上でのデプロイ パッケージからの実行をサポートするには、linuxFxVersion サイトの構成設定を DOTNET-ISOLATED|7.0 に更新する必要もあります。 詳細については、「Linux 上でのバージョンの手動更新」を参照してください。

パッケージ参照

分離ワーカー モデルを使用する 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# を使用してアプリケーションを作成する場合、一部のトリガーおよびバインド拡張機能では、ここで追加の構成が必要になります。 アプリでこれを使用する予定の場合は、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()

ホスト ビルダー パイプラインにアクセスできるということは、初期化中にあらゆるアプリ固有の構成を設定できることも意味します。 ConfigureAppConfiguration メソッドを HostBuilder で 1 回以上呼び出して、関数アプリに必要な構成を追加できます。 アプリ構成について詳しくは、「ASP.NET Core の構成」を参照してください。

これらの構成は、別のプロセスで実行している関数アプリに適用されます。 Functions ホストまたはトリガー、およびバインド構成に変更を加えるには、この場合も host.json ファイルを使用する必要があります。

依存関係の挿入

依存関係の挿入は、.NET クラス ライブラリと比べると簡単です。 サービスを登録するためのスタートアップ クラスを作成するのではなく、ホスト ビルダーで ConfigureServices を呼び出して、IServiceCollection で拡張メソッドを使用して特定のサービスを挿入するだけで済みます。

次の例では、シングルトン サービスの依存関係を挿入します。

.ConfigureServices(services =>
{
    services.AddSingleton<IHttpResponderService, DefaultHttpResponderService>();
})

このコードでは using Microsoft.Extensions.DependencyInjection; が必要です。 詳細については、「ASP.NET Core での依存関係の挿入」を参照してください。

Azure クライアントを登録する

依存関係の挿入は、他の Azure サービスと対話するために使用できます。 Microsoft.Extensions.Azure パッケージを使って、Azure SDK for .NET からクライアントを挿入できます。 パッケージをインストールした後、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 インスタンスを取得します。 このメソッドは、要求ヘッダーや Cookie などのメッセージ データを読み取るときに便利な ValueTask<HttpRequestData?> のインスタンスを返します。
GetHttpResponseData HTTP トリガーによって呼び出されたときに HttpResponseData インスタンスを取得します。
GetInvocationResult 現在の関数実行の結果を表す InvocationResult のインスタンスを取得します。 Value プロパティを使用して、必要に応じて値を取得または設定します。
GetOutputBindings 現在の関数実行の出力バインド エントリを取得します。 このメソッドの結果の各エントリの型は OutputBindingData です。 Value プロパティを使用して、必要に応じて値を取得または設定できます。
BindInputAsync 要求された BindingMetadata インスタンスの入力バインド項目をバインドします。 たとえば、ミドルウェアからアクセスまたは更新する必要がある BlobInput 入力バインドを持つ関数があるときに、このメソッドを使用できます。

関数の実行中に HttpRequestData インスタンスを読み取り、HttpResponseData インスタンスを更新するミドルウェア実装の例を次に示します。 このミドルウェアは、特定の要求ヘッダー (x-correlationId) の存在を確認し、存在するときはヘッダー値を使用して応答ヘッダーをスタンプします。 それ以外の場合は、新しい GUID 値を生成し、それを使用して応答ヘッダーをスタンプします。

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

関数アプリでカスタム ミドルウェアを使用する詳細な例については、カスタム ミドルウェアのリファレンス サンプルを参照してください。

キャンセル トークン

関数は 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);
    }
}

パフォーマンスの最適化

このセクションでは、コールド スタートに関するパフォーマンスを向上させるために有効にできるオプションの概要について説明します。

通常アプリでは、最新バージョンのコア依存関係を使用する必要があります。 少なくとも、プロジェクトを次のように更新する必要があります。

  • Microsoft.Azure.Functions.Worker をバージョン 1.19.0 以降にアップグレードします。
  • Microsoft.Azure.Functions.Worker.Sdk バージョン 1.16.2 以降にアップグレードします。
  • アプリで .NET Framework をターゲットにする場合を除き、Microsoft.AspNetCore.App にフレームワーク参照を追加します。

次の例は、プロジェクト ファイルのコンテキストでこの構成を示しています。

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.19.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.2" />
  </ItemGroup>

プレースホルダー

プレースホルダーは、.NET 6 以降をターゲットにするアプリのコールド スタートを改善するプラットフォーム機能です。 この機能では、オプトイン構成が一部必要となります。 プレースホルダーを有効にするには、次の手順を実行します。

  • 前のセクションで詳しく説明したようにプロジェクトを更新します。
  • WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED アプリケーションの設定を "1" に設定します。
  • 関数アプリの netFrameworkVersion プロパティがプロジェクトのターゲット フレームワーク (.NET 6 以降である必要があります) と一致していることを確認します。
  • 関数アプリが 64 ビット プロセスを使用するように構成されていることを確かめます。

重要

WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED を "1" に設定する場合、構成のその他すべての側面を正しく設定する必要があります。 偏差は起動の失敗の原因となる可能性があります。

次の CLI コマンドでは、アプリケーション設定を設定し、netFrameworkVersion プロパティを更新して、アプリを 64 ビットとして実行します。 <groupName> をリソース グループの名前に置き換え、<appName> を関数アプリの名前に置き換えます。 <framework> を、ターゲットの .NET バージョンに応じて "v8.0"、"v7.0"、"v6.0" などの適切なバージョン文字列に置き換えます。

az functionapp config appsettings set -g <groupName> -n <appName> --settings 'WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED=1'
az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>
az functionapp config set -g <groupName> -n <appName> --use-32bit-worker-process false

最適化された Executor

関数 Executor は、呼び出しを実行するプラットフォームのコンポーネントです。 このコンポーネントの最適化されたバージョンは、SDK のバージョン 1.16.2 以降で既定で有効になっています。 追加の構成は不要です。

ReadyToRun

関数アプリは ReadyToRun バイナリとしてコンパイルできます。 ReadyToRun は、事前コンパイル形式であり、起動時のパフォーマンスを向上させることができます。これは、従量課金プランで実行される場合にコールド スタートの影響を軽減するのに役立ちます。 ReadyToRun は .NET 6 以降のバージョンで使用可能であり、Azure Functions ランタイムのバージョン 4.0 以降が必要です。

ReadyToRun では、ホスティング アプリのランタイム アーキテクチャに対してプロジェクトをビルドする必要があります。 これらが配置されていない場合は、起動時にアプリでエラーが発生します。 次の表からランタイム識別子を選択します。

オペレーティング システム アプリは 32 ビットです1 ランタイム識別子
Windows 正しい win-x86
Windows いいえ win-x64
Linux 正しい 該当なし (サポートされていません)
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 では、発行プロファイルの "ターゲット ランタイム" オプションを正しいランタイム識別子に設定する必要があります。 既定値 "Portable" に設定されている場合、ReadyToRun は使用されません。

実行コンテキスト

.NET 分離は FunctionContext オブジェクトを関数メソッドに渡します。 このオブジェクトを使用すれば、ログに書き込む ILoggerILogger インスタンスを取得できます。これは、GetLogger メソッドを呼び出して ILogger 文字列を指定することで実行します。 詳細については、「ログ」を参照してください。

バインド

バインドは、メソッド、パラメーター、および戻り値の型の属性を使用して定義します。 関数メソッドとは、次の例に示すように、Function 属性とトリガー属性が入力パラメーターに適用されたメソッドです。

[Function(nameof(QueueFunction))]
[QueueOutput("output-queue")]
public string[] Run([QueueTrigger("input-queue")] Album myQueueItem, FunctionContext context)

トリガー属性は、トリガーの種類を指定し、メソッド パラメーターに入力データをバインドします。 前の例の関数はキュー メッセージによってトリガーされ、そのキュー メッセージは myQueueItem パラメーターでメソッドに渡されます。

Function 属性は、関数のエントリ ポイントとしてメソッドをマークします。 名前はプロジェクト内で一意であり、文字で始まり、英数字、_- のみが含まれ、127 文字以下にする必要があります。 プロジェクト テンプレートでは、多くの場合、Run という名前のメソッドが作成されますが、有効な C# メソッド名であればメソッド名として使用できます。

バインドでは、文字列、配列、および単純な従来のクラス オブジェクト (POCO) のようなシリアル化可能型としてデータを提供できます。 一部のサービス SDK の型にバインドすることもできます。 HTTP トリガーについては、以下の HTTP トリガー に関するセクションを参照してください。

分離ワーカー プロセスでトリガーとバインドを使用するためのリファレンス サンプルの全セットについては、バインド拡張機能のリファレンス サンプルを参照してください。

入力バインディング

関数には、関数にデータを渡すことができる入力バインディングを 0 個以上含めることができます。 トリガーと同様、入力バインディングは、入力パラメーターにバインディング属性を適用することによって定義します。 関数を実行すると、ランタイムはバインディングで指定されたデータを取得しようとします。 要求されるデータは、多くの場合、バインディング パラメーターを使用してトリガーから提供される情報に依存します。

出力バインディング

出力バインディングに書き込むには、関数メソッドに、バインドされたサービスへの書き込み方法を定義した出力バインディング属性を適用する必要があります。 メソッドによって返される値は、出力バインディングに書き込まれます。 たとえば、次の例では、出力バインディングを使用して、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;
}

複数の出力バインディング

出力バインディングに書き込まれるデータは、常に関数の戻り値です。 複数の出力バインディングに書き込む必要がある場合は、カスタムの戻り値の型を作成する必要があります。 この戻り値の型では、出力バインディング属性はクラスの 1 つ以上のプロパティに適用されていなければなりません。 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 Service Bus 一般提供 "入力バインドは存在しません" SDK の型は推奨されません。1
Azure Event Hubs 一般提供 "入力バインドは存在しません" SDK の型は推奨されません。1
Azure Cosmos DB SDK 型は使用されません2 一般提供 SDK の型は推奨されません。1
Azure テーブル "トリガーが存在しません" 一般提供 SDK の型は推奨されません。1
Azure Event Grid 一般提供 "入力バインドは存在しません" SDK の型は推奨されません。1

1 SDK の型を使用する出力シナリオでは、出力バインドを使用する代わりに、SDK クライアントを直接作成して操作する必要があります。 依存関係の挿入を使ってこれを行う方法の例については、「Azure クライアントの登録」を参照してください。

2 Cosmos DB トリガーでは、Azure Cosmos DB の変更フィードが使用され、変更フィードの項目が JSON シリアル化可能な型として公開されます。 このシナリオの設計により、SDK 型は存在しません。

Note

トリガー データに依存するバインド式を使用するとき、トリガー自体の SDK の型は使用できません。

HTTP トリガー

HTTP トリガーを使用すると、HTTP 要求によって関数を呼び出せます。 使用できる方法は 2 つあります。

ASP.NET Core の統合

このセクションでは、HttpRequestHttpResponseIActionResult などの ASP.NET Core の型を使用して、基になる HTTP 要求オブジェクトと応答オブジェクトを操作する方法について説明します。 このモデルは、.NET Framework を対象とするアプリでは使用できません。代わりに、組み込みのモデルを活用する必要があります。

注意

ASP.NET Core の全機能がこのモデルによって公開されるわけではありません。 具体的には、ASP.NET Core ミドルウェア パイプラインとルーティング機能は使用できません。

  1. Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore NuGet パッケージ バージョン 1.0.0 以降への参照をプロジェクトに追加します。

    また、Microsoft.Azure.Functions.Worker.Sdk のバージョン 1.11.0 以降Microsoft.Azure.Functions.Worker のバージョン 1.16.0 以降を使用するようにプロジェクトを更新する必要があります。

  2. Program.cs ファイルで、ConfigureFunctionsWorkerDefaults() の代わりに ConfigureFunctionsWebApplication() を使用するようにホスト ビルダーの構成を更新します。 次の例は、他のカスタマイズを行わない最小限のセットアップを示しています。

    using Microsoft.Extensions.Hosting;
    using Microsoft.Azure.Functions.Worker;
    
    var host = new HostBuilder()
        .ConfigureFunctionsWebApplication()
        .Build();
    
    host.Run();
    
  3. その後、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 モデルでは、システムは受信した HTTP 要求メッセージを、関数に渡される HttpRequestData オブジェクトに変換します。 このオブジェクトは、HeadersCookiesIdentitiesURL、メッセージ Body (オプション) を含む、要求からのデータを提供します。 このオブジェクトは HTTP 要求の表現ですが、基になる HTTP リスナーまたは受信したメッセージには直接接続されません。

同様に、関数が返す HttpResponseData オブジェクトも、メッセージ StatusCodeHeaders、およびメッセージ Body (オプション) を含む、HTTP 応答を作成するために使用するデータを提供します。

次の例は、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;
}

Logging

.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 を直接操作するには、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() を呼び出すと、Functions で定義された ActivitySource に対する ITelemetryModule のリッスンが追加されます。 これにより、Application Insights で分散トレースをサポートするために必要な依存関係テレメトリが作成されます。 AddApplicationInsightsTelemetryWorkerService() の詳細とその使用方法については、「Application Insights for Worker Service アプリケーション」を参照してください。

重要

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

.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> はワーカー プロセスの ID です。 これで、Visual Studio を使用して、プロセスに手動でアタッチできるようになりました。 この操作の手順については、実行中のプロセスにアタッチする方法に関する記事を参照してください。

デバッガーがアタッチされると、プロセスの実行が再開され、デバッグできるようになります。

Visual Studio を使用したリモート デバッグ

分離ワーカー プロセス アプリは Functions ランタイムの外部で実行されるため、リモート デバッガーを別のプロセスにアタッチする必要があります。 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 ツールおよびテンプレートを必ず使用してください。 これらを更新するには、Tools->Options に移動し、Projects and Solutions の下にある Azure Functions を選んで Check for updates をクリックし、プロンプトに従って更新プログラムをインストールします。

プレビュー期間中、開発環境の .NET プレビューのバージョンは、ホストされているサービスよりも新しいバージョンである可能性があります。 これにより、アプリケーションのデプロイ時に失敗する可能性があります。 これに対処するには、global.json で使う SDK のバージョンを構成します。 まず、dotnet --list-sdks を使ってインストールしたバージョンを特定し、サービスでサポートされるバージョンと一致するバージョンをメモします。 次に、<sdk-version> を前のコマンドでメモしたバージョンに置き換えて dotnet new globaljson --sdk-version <sdk-version> --force を実行します。 たとえば、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 バージョンと比較してコールド スタート時間が長くなる可能性があることに注意してください。

次のステップ