Guida di riferimento per gli sviluppatori C# di Funzioni di AzureAzure Functions C# developer reference

Questo articolo è un'introduzione allo sviluppo di Funzioni di Azure tramite C# nelle librerie di classi .NET.This article is an introduction to developing Azure Functions by using C# in .NET class libraries.

Funzioni di Azure supporta i linguaggi di programmazione C# e script C#.Azure Functions supports C# and C# script programming languages. Per materiale sussidiario sull'uso di C# nel portale di Azure, vedere Guida di riferimento a per sviluppatori di script C# (.csx).If you're looking for guidance on using C# in the Azure portal, see C# script (.csx) developer reference.

Questo articolo presuppone che l'utente abbia già letto gli articoli seguenti:This article assumes that you've already read the following articles:

Progetto di libreria di classi per FunzioniFunctions class library project

In Visual Studio il modello di progetto Funzioni di Azure crea un progetto di libreria di classi C# contenente i file seguenti:In Visual Studio, the Azure Functions project template creates a C# class library project that contains the following files:

  • host.json: archivia le impostazioni di configurazione che interessano tutte le funzioni del progetto quando vengono eseguite nell'ambiente locale o in Azure.host.json - stores configuration settings that affect all functions in the project when running locally or in Azure.
  • local.settings.json: archivia le impostazioni dell'app e le stringhe di connessione usate per l'esecuzione nell'ambiente locale.local.settings.json - stores app settings and connection strings that are used when running locally.

Attributi FunctionName e triggerFunctionName and trigger attributes

In una libreria di classi, una funzione è un metodo statico con un attributo FunctionName e trigger, come illustrato nell'esempio seguente:In a class library, a function is a static method with a FunctionName and a trigger attribute, as shown in the following example:

public static class SimpleExample
{
    [FunctionName("QueueTrigger")]
    public static void Run(
        [QueueTrigger("myqueue-items")] string myQueueItem, 
        TraceWriter log)
    {
        log.Info($"C# function processed: {myQueueItem}");
    }
} 

L'attributo FunctionName indica il metodo come punto di ingresso della funzione.The FunctionName attribute marks the method as a function entry point. Il nome deve essere univoco nel progetto.The name must be unique within a project.

L'attributo trigger specifica il tipo di trigger e associa i dati di input a un parametro del metodo.The trigger attribute specifies the trigger type and binds input data to a method parameter. La funzione di esempio viene attivata da un messaggio della coda e il messaggio della coda viene passato al metodo nel parametro myQueueItem.The example function is triggered by a queue message, and the queue message is passed to the method in the myQueueItem parameter.

Altri attributi di associazioneAdditional binding attributes

È possibile usare altri attributi di associazione di input e output.Additional input and output binding attributes may be used. L'esempio seguente differisce dal precedente per l'aggiunta di un'associazione di coda di output.The following example modifies the preceding one by adding an output queue binding. La funzione scrive il messaggio della coda di input in un nuovo messaggio di un'altra coda.The function writes the input queue message to a new queue message in a different queue.

public static class SimpleExampleWithOutput
{
    [FunctionName("CopyQueueMessage")]
    public static void Run(
        [QueueTrigger("myqueue-items-source")] string myQueueItem, 
        [Queue("myqueue-items-destination")] out string myQueueItemCopy,
        TraceWriter log)
    {
        log.Info($"CopyQueueMessage function processed: {myQueueItem}");
        myQueueItemCopy = myQueueItem;
    }
}

Conversione in function.jsonConversion to function.json

Il processo di compilazione crea un file function.json in una cartella della funzione nella cartella di compilazione.The build process creates a function.json file in a function folder in the build folder. Questo file non viene modificato direttamente.This file is not meant to be edited directly. Non è possibile modificare la configurazione di associazione o disabilitare la funzione modificando il file.You can't change binding configuration or disable the function by editing this file.

Lo scopo di questo file è fornire informazioni che il controller di scalabilità userà per decisioni di scalabilità nel piano a consumo.The purpose of this file is to provide information to the scale controller to use for scaling decisions on the consumption plan. Per questo motivo il file contiene solo informazioni di trigger, non associazioni di input o output.For this reason, the file only has trigger info, not input or output bindings.

Il file function.json generato include una proprietà configurationSource che indica al runtime di usare gli attributi .NET per le associazioni invece della configurazione function.json.The generated function.json file includes a configurationSource property that tells the runtime to use .NET attributes for bindings, rather than function.json configuration. Ad esempio:Here's an example:

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-1.0.0.0",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "queueTrigger",
      "queueName": "%input-queue-name%",
      "name": "myQueueItem"
    }
  ],
  "disabled": false,
  "scriptFile": "..\\bin\\FunctionApp1.dll",
  "entryPoint": "FunctionApp1.QueueTrigger.Run"
}

La generazione del file function.json viene eseguita dal pacchetto NuGet Microsoft.NET.Sdk.Functions.The function.json file generation is performed by the NuGet package Microsoft.NET.Sdk.Functions. Il codice sorgente è disponibile nel repository GitHub azure-functions-vs-build-sdk.The source code is available in the GitHub repo azure-functions-vs-build-sdk.

Tipi supportati per le associazioniSupported types for bindings

Ogni associazione supporta determinati tipi. Ad esempio è possibile applicare un attributo trigger di BLOB a un parametro stringa, un parametro POCO, un parametro CloudBlockBlob o uno dei molti altri tipi supportati.Each binding has its own supported types; for instance, a blob trigger attribute can be applied to a string parameter, a POCO parameter, a CloudBlockBlob parameter, or any of several other supported types. L'articolo di riferimento sull'associazione relativo alle associazioni BLOB elenca tutti i tipi di parametri supportati.The binding reference article for blob bindings lists all supported parameter types. Per altre informazioni, vedere Trigger e associazioni e i documenti di riferimento per ogni tipo di associazione.For more information, see Triggers and bindings and the binding reference docs for each binding type.

Suggerimento

Se si prevede di usare binding HTTP o WebHook, evitare l'esaurimento delle porte che può essere causato da un'errata creazione di istanze di HttpClient.If you plan to use the HTTP or WebHook bindings, plan to avoid port exhaustion that can be caused by improper instantiation of HttpClient. Per altre informazioni, vedere l'articolo Improper Instantiation antipattern (Antipattern non valido per la creazione di istanze).For more information, review the article Improper Instantiation antipattern.

Associazione al valore restituito dal metodoBinding to method return value

È possibile usare un valore restituito dal metodo per un'associazione di output, come illustrato nell'esempio seguente:You can use a method return value for an output binding, as shown in the following example:

public static class ReturnValueOutputBinding
{
    [FunctionName("CopyQueueMessageUsingReturnValue")]
    [return: Queue("myqueue-items-destination")]
    public static string Run(
        [QueueTrigger("myqueue-items-source-2")] string myQueueItem,
        TraceWriter log)
    {
        log.Info($"C# function processed: {myQueueItem}");
        return myQueueItem;
    }
}

Scrittura di più valori di outputWriting multiple output values

Per scrivere più valori in un'associazione di output, usare i tipi ICollector o IAsyncCollector .To write multiple values to an output binding, use the ICollector or IAsyncCollector types. Questi tipi sono raccolte di sola scrittura che vengono scritte nell'associazione di output durante il completamento del metodo.These types are write-only collections that are written to the output binding when the method completes.

Questo esempio scrive più messaggi in coda nella stessa coda usando ICollector:This example writes multiple queue messages into the same queue using ICollector:

public static class ICollectorExample
{
    [FunctionName("CopyQueueMessageICollector")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-3")] string myQueueItem,
        [Queue("myqueue-items-destination")] ICollector<string> myQueueItemCopy,
        TraceWriter log)
    {
        log.Info($"C# function processed: {myQueueItem}");
        myQueueItemCopy.Add($"Copy 1: {myQueueItem}");
        myQueueItemCopy.Add($"Copy 2: {myQueueItem}");
    }
}

RegistrazioneLogging

Per registrare l'output nei log in streaming in C#, includere un argomento di tipo TraceWriter.To log output to your streaming logs in C#, include an argument of type TraceWriter. È consigliabile denominarlo log.We recommend that you name it log. Evitare di usare Console.Write in Funzioni di Azure.Avoid using Console.Write in Azure Functions.

TraceWriter è definito in Azure WebJobs SDK.TraceWriter is defined in the Azure WebJobs SDK. Il livello di registrazione per TraceWriter può essere configurato in host.json.The log level for TraceWriter can be configured in host.json.

public static class SimpleExample
{
    [FunctionName("QueueTrigger")]
    public static void Run(
        [QueueTrigger("myqueue-items")] string myQueueItem, 
        TraceWriter log)
    {
        log.Info($"C# function processed: {myQueueItem}");
    }
} 

Nota

Per informazioni su un framework di registrazione più recente che è possibile usare al posto di TraceWriter, vedere Scrivere i log nelle funzioni C# nell'articolo Monitorare Funzioni di Azure.For information about a newer logging framework that you can use instead of TraceWriter, see Write logs in C# functions in the Monitor Azure Functions article.

AsyncAsync

Per rendere una funzione asincrona, usare la parola chiave async e restituire un oggetto Task.To make a function asynchronous, use the async keyword and return a Task object.

public static class AsyncExample
{
    [FunctionName("BlobCopy")]
    public static async Task RunAsync(
        [BlobTrigger("sample-images/{blobName}")] Stream blobInput,
        [Blob("sample-images-copies/{blobName}", FileAccess.Write)] Stream blobOutput,
        CancellationToken token,
        TraceWriter log)
    {
        log.Info($"BlobCopy function processed.");
        await blobInput.CopyToAsync(blobOutput, 4096, token);
    }
}

Token di annullamentoCancellation tokens

Alcune operazioni richiedono l'arresto normale.Some operations require graceful shutdown. Anche se è sempre preferibile scrivere codice che possa gestire gli arresti anomali, quando si vogliono gestire le richieste di arresto definire un argomento tipizzato CancellationToken.While it's always best to write code that can handle crashing, in cases where you want to handle shutdown requests, define a CancellationToken typed argument. È fornito un CancellationToken per segnalare che viene avviato un arresto dell'host.A CancellationToken is provided to signal that a host shutdown is triggered.

public static class CancellationTokenExample
{
    [FunctionName("BlobCopy")]
    public static async Task RunAsync(
        [BlobTrigger("sample-images/{blobName}")] Stream blobInput,
        [Blob("sample-images-copies/{blobName}", FileAccess.Write)] Stream blobOutput,
        CancellationToken token)
    {
        await blobInput.CopyToAsync(blobOutput, 4096, token);
    }
}

Variabili di ambienteEnvironment variables

Per ottenere una variabile di ambiente o un valore di impostazione dell'app, usare System.Environment.GetEnvironmentVariablecome illustrato nell'esempio di codice seguente:To get an environment variable or an app setting value, use System.Environment.GetEnvironmentVariable, as shown in the following code example:

public static class EnvironmentVariablesExample
{
    [FunctionName("GetEnvironmentVariables")]
    public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, TraceWriter log)
    {
        log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
        log.Info(GetEnvironmentVariable("AzureWebJobsStorage"));
        log.Info(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
    }

    public static string GetEnvironmentVariable(string name)
    {
        return name + ": " +
            System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
    }
}

Associazione in fase di esecuzioneBinding at runtime

In C# e altri linguaggi .NET, è possibile usare un modello di associazione imperativo anziché dichiarativo negli attributi.In C# and other .NET languages, you can use an imperative binding pattern, as opposed to the declarative bindings in attributes. L'associazione imperativa è utile quando i parametri di associazione devono essere calcolati in fase di runtime invece che in fase di progettazione.Imperative binding is useful when binding parameters need to be computed at runtime rather than design time. Con questo modello è possibile associare rapidamente i dati ad associazioni di input e output supportate nel codice della funzione.With this pattern, you can bind to supported input and output bindings on-the-fly in your function code.

Definire un'associazione imperativa, come segue:Define an imperative binding as follows:

  • Non includere un attributo nella firma della funzione per le associazioni imperative.Do not include an attribute in the function signature for your desired imperative bindings.
  • Passare un parametro di input Binder binder o IBinder binder.Pass in an input parameter Binder binder or IBinder binder.
  • Usare il seguente modello C# per eseguire l'associazione dati.Use the following C# pattern to perform the data binding.

    using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...)))
    {
        ...
    }
    

    BindingTypeAttribute è l'attributo .NET che definisce l'associazione e T è un tipo di input o output supportato da quel tipo di associazione.BindingTypeAttribute is the .NET attribute that defines your binding, and T is an input or output type that's supported by that binding type. T non può essere un tipo di parametro out, ad esempio out JObject.T cannot be an out parameter type (such as out JObject). L'associazione di output della tabella App per dispositivi mobili supporta ad esempio sei tipi di output, ma è possibile usare solo ICollector o IAsyncCollector con l'associazione imperativa.For example, the Mobile Apps table output binding supports six output types, but you can only use ICollector or IAsyncCollector with imperative binding.

Esempio con un solo attributoSingle attribute example

L'esempio di codice seguente crea un associazione di output del BLOB di archiviazione con percorso del BLOB definito in fase di esecuzione, quindi scrive una stringa per il BLOB.The following example code creates a Storage blob output binding with blob path that's defined at run time, then writes a string to the blob.

public static class IBinderExample
{
    [FunctionName("CreateBlobUsingBinder")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-4")] string myQueueItem,
        IBinder binder,
        TraceWriter log)
    {
        log.Info($"CreateBlobUsingBinder function processed: {myQueueItem}");
        using (var writer = binder.Bind<TextWriter>(new BlobAttribute(
                    $"samples-output/{myQueueItem}", FileAccess.Write)))
        {
            writer.Write("Hello World!");
        };
    }
}

BlobAttribute definisce l'associazione di input o output del BLOB di archiviazione e TextWriter è un tipo di associazione di output supportato.BlobAttribute defines the Storage blob input or output binding, and TextWriter is a supported output binding type.

Esempio con più attributiMultiple attribute example

L'esempio precedente ottiene l'impostazione dell'app per la stringa di connessione dell'account di archiviazione principale dell'app, ovvero AzureWebJobsStorage.The preceding example gets the app setting for the function app's main Storage account connection string (which is AzureWebJobsStorage). È possibile specificare un'impostazione app personalizzata da usare per l'account di archiviazione aggiungendo StorageAccountAttribute e passando la matrice di attributi in BindAsync<T>().You can specify a custom app setting to use for the Storage account by adding the StorageAccountAttribute and passing the attribute array into BindAsync<T>(). Usare un parametro Binder e non IBinder.Use a Binder parameter, not IBinder. Ad esempio: For example:

public static class IBinderExampleMultipleAttributes
{
    [FunctionName("CreateBlobInDifferentStorageAccount")]
    public async static Task RunAsync(
            [QueueTrigger("myqueue-items-source-binder2")] string myQueueItem,
            Binder binder,
            TraceWriter log)
    {
        log.Info($"CreateBlobInDifferentStorageAccount function processed: {myQueueItem}");
        var attributes = new Attribute[]
        {
        new BlobAttribute($"samples-output/{myQueueItem}", FileAccess.Write),
        new StorageAccountAttribute("MyStorageAccount")
        };
        using (var writer = await binder.BindAsync<TextWriter>(attributes))
        {
            await writer.WriteAsync("Hello World!!");
        }
    }
}

Trigger e associazioniTriggers and bindings

La tabella seguente elenca i trigger e gli attributi di associazione disponibili in un progetto di libreria di classi di Funzioni di Azure.The following table lists the trigger and binding attributes that are available in an Azure Functions class library project. Tutti gli attributi sono contenuti nello spazio dei nomi Microsoft.Azure.WebJobs.All attributes are in the namespace Microsoft.Azure.WebJobs.

TriggerTrigger InputInput OutputOutput
BlobTriggerBlobTrigger BLOBBlob BLOBBlob
CosmosDBTriggerCosmosDBTrigger DocumentDBDocumentDB DocumentDBDocumentDB
EventHubTriggerEventHubTrigger EventHubEventHub
HTTPTriggerHTTPTrigger
QueueTriggerQueueTrigger CodaQueue
ServiceBusTriggerServiceBusTrigger Bus di servizioServiceBus
TimerTriggerTimerTrigger
ApiHubFileApiHubFile ApiHubFileApiHubFile
MobileTableMobileTable MobileTableMobileTable
TabellaTable TabellaTable
NotificationHubNotificationHub
SendGridSendGrid
TwilioTwilio

Passaggi successiviNext steps