web-dev-qa-db-ja.com

タイマーでトリガーされるAzure Functionをローカルで1回実行する最も簡単な方法は何ですか?

timer triggers を使用してスケジュールで実行されるC#Azure関数がいくつかあります。このように設定しました。_%TimerSchedule%_は、アプリ設定のcron式を指します。

_public static void Run([TimerTrigger("%TimerSchedule%")]TimerInfo myTimer, TraceWriter log)
_

開発中に、Visual Studio用のAzure Functionsツール+ Azure Functionsコアツールを使用して、関数をローカルで実行することがよくあります。しかし、関数をローカルでデバッグするためにF5を押すと、(通常)すぐには実行されません。代わりに、タイマースケジュールに従って次の発生を待機し始めます。たとえば、cron式が毎日午後8時に実行するように指定した場合、関数が実際にマシンで実行されるまで午後8時まで待たなければなりません。

だから私の質問は次のとおりです:関数をローカルで1回実行する最も簡単で最良の方法は何ですか?

私が試したり検討したこと:

  1. ローカル開発のためだけに、より頻繁なタイマースケジュールを使用する
    • これは問題ありませんが、完璧ではありません。非常に頻繁でない限り、少し待つ必要があります。非常に頻繁な場合、関数は複数回実行される可能性があります。これは私が今やっていることです。
  2. 関数のRun()メソッドを直接呼び出すコンソールアプリまたは単体テストを作成します
    • TimerInfo引数とTraceWriter引数をRun()に提供する必要があるため、これは100%簡単ではありません。そのための驚くほど少ないドキュメントが見つかりました。

Microsoftの Azure Functionsでコードをテストするための戦略 ページは、このトピックではあまり役に立ちません。テストする方法としてタイマートリガーについてのみ言及していますotherトリガータイプ。

完璧な世界では、F5キーを押すと、関数がすぐに1回実行されます。これは、「通常の」.NETアプリの開発と同じです。

35
ripley_

おそらく here のようにRunOnStartupフラグを使用できます。一度だけ実行されるという点については、簡単に説明できませんが、少なくともアプリが起動したらローカルで実行する必要があります。

_/// Gets or sets a value indicating whether the function should be invoked
/// immediately on startup. After the initial startup run, the function will
/// be run on schedule thereafter.
_

属性バインディングを使用した例:

[TimerTrigger("%TimerSchedule%", RunOnStartup = true)]TimerInfo myTimer

53
Wah Yuen

私は同じ質問を持っていて、デバッグ中にのみRunOnStartupを持つためにDEBUGフラグを使用しました:

        public static void Run(
            [TimerTrigger("* 0 7 * * 1-5"
#if DEBUG
            , RunOnStartup=true
#endif
            )]TimerInfo myTimer, TraceWriter log)
        {
33
BerDev

同じ質問がありました。 Unittestで修正しました。実際、TraceWriterとTimerInfoをスタブする必要があります。

ここに、私がこれをどのように行うかのコードがあります。

TimerInfo:

public class ScheduleStub : TimerInfo
{
    public ScheduleStub(TimerSchedule schedule, ScheduleStatus status, bool isPastDue = false) : base(schedule, status, isPastDue)
    {
    }
}

そしてTraceWriter:

 public class TraceWriterStub : TraceWriter
{
    protected TraceLevel _level;
    protected List<TraceEvent> _traces;

    public TraceWriterStub(TraceLevel level) : base(level)
    {
        _level = level;
        _traces = new List<TraceEvent>();
    }

    public override void Trace(TraceEvent traceEvent)
    {
        _traces.Add(traceEvent);
    }

    public List<TraceEvent> Traces => _traces;
}
4
StefanHa

同じクラス内にHTTPトリガータイプを持つ別の関数を追加するか、コードを追加するか、その関数からRunメソッドを呼び出してブラウザーから呼び出します。

Prodにデプロイするときは、必ずその関数をコメント/削除してください。そうしないと、prodのHTTP呼び出しを介して関数をトリガーできます。

0
Mike Cardona