Durable Functions (Azure Functions) 中的計時器

Durable Functions 提供「永久性計時器」,用於協調器函式中實作延遲,或在非同步動作上設定逾時。 永久性計時器應該用於協調器函式,而不是可能內建於語言中的「睡眠」或「延遲」API。

永久性計時器是針對所提供語言使用適當的「建立計時器」API 所建立的工作,如下所示,並以到期時間或持續時間作為引數。

// Put the orchestrator to sleep for 72 hours
DateTime dueTime = context.CurrentUtcDateTime.AddHours(72);
await context.CreateTimer(dueTime, CancellationToken.None);

當您「等候」計時器工作時,協調器函式會進入睡眠,直到指定的到期時間為止。

注意

協調流程會在等候計時器工作到期時,繼續處理其他傳入事件。

計時器限制

當您建立一個在 UTC 下午 4:30 過期的計時器時,基礎「永久性工作架構」會將訊息加入佇列,而此訊息只在 UTC 下午 4:30 出現。 如果在此期間,函數應用程式縮小為零個執行個體,則可見的新計時器訊息可確保函數應用程式會在合適的 VM 上再次啟動。

注意

  • 若是 JavaScript、Python 和 PowerShell 應用程式,永久性計時器的限制為六天。 若要因應這項限制,您可以使用 while 迴圈中的計時器 API 來模擬較長的延遲。 最新的 .NET 和 JAVA 應用程式支援沒有長度限制的計時器。
  • 視所使用的 SDK 版本和儲存體提供者,6 天以上的長時間計時器可能是使用一連串較短的計時器 (例如持續時間為 3 天的計時器) 直到達到所需的到期時間,以此方式在內部實作而成。 這可以在基礎資料存放區中觀察到,但不影響協調流程行為。
  • 請勿使用內建的日期/時間 API 來取得目前時間。 計算計時器到期的未來日期時,請一律使用協調器函式的目前時間 API。 如需詳細資訊,請參閱協調器函數程式碼條件約束一文。

延遲的使用方式

下列範例說明如何使用永久性計時器來延遲執行。 此範例會每天發出帳單通知 10 天。

[FunctionName("BillingIssuer")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    for (int i = 0; i < 10; i++)
    {
        DateTime deadline = context.CurrentUtcDateTime.Add(TimeSpan.FromDays(1));
        await context.CreateTimer(deadline, CancellationToken.None);
        await context.CallActivityAsync("SendBillingEvent");
    }
}

注意

先前的 C# 範例是針對 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 DurableOrchestrationContext 而不是 IDurableOrchestrationContext。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

警告

在協調器函式中避免無限迴圈。 如需有關如何安全而有效率地實作無限迴圈案例的資訊,請參閱永久性協調流程

逾時的使用方式

此範例說明如何使用永久性計時器來實作逾時。

[FunctionName("TryGetQuote")]
public static async Task<bool> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    TimeSpan timeout = TimeSpan.FromSeconds(30);
    DateTime deadline = context.CurrentUtcDateTime.Add(timeout);

    using (var cts = new CancellationTokenSource())
    {
        Task activityTask = context.CallActivityAsync("GetQuote");
        Task timeoutTask = context.CreateTimer(deadline, cts.Token);

        Task winner = await Task.WhenAny(activityTask, timeoutTask);
        if (winner == activityTask)
        {
            // success case
            cts.Cancel();
            return true;
        }
        else
        {
            // timeout case
            return false;
        }
    }
}

注意

先前的 C# 範例是針對 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 DurableOrchestrationContext 而不是 IDurableOrchestrationContext。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

警告

在 .NET、JavaScript、Python 和 PowerShell 中,如果您的程式碼不會等待計時器完成,則您必須取消任何建立的永久性計時器。 如需如何取消暫止計時器,請參閱上述範例。 等到所有未完成的工作 (包含永久性計時器工作) 都完成或取消之後,「永久性工作架構」才會將協調流程的狀態變更為「已完成」。

這個使用 when-any 模式的取消機制不會終止進行中的活動函式或子協調流程執行。 只是讓協調器函式略過結果並繼續執行。 如果函數應用程式使用取用量方案,您仍然要為已放棄的活動函數所耗用的任何時間和記憶體付費。 根據預設,在取用量方案中執行的函式會在五分鐘後逾時。 如果超過此限制,Azure Functions 主機會重新開機來停止所有執行,以避免計費失控狀況發生。 函式逾時可設定

如需如何在協調器函數中實作逾時的更深入範例,請參閱人為互動和逾時 - 電話驗證一文。

下一步