J'ai quelques fonctions Azure C # qui s'exécutent selon un calendrier utilisant déclencheurs de minuterie . Je les ai configurés comme ça, où %TimerSchedule%
Fait référence à une expression cron dans les paramètres de l'application:
public static void Run([TimerTrigger("%TimerSchedule%")]TimerInfo myTimer, TraceWriter log)
Pendant le développement, je souhaite souvent exécuter les fonctions localement à l'aide des outils Azure Functions pour Visual Studio + Azure Functions Core Tools. Mais lorsque j'appuie sur F5 pour déboguer la fonction localement, elle ne s'exécute pas (généralement) immédiatement. Au lieu de cela, il commence à attendre la prochaine occurrence selon le calendrier du minuteur. Ainsi, par exemple, si mon expression cron dit de s'exécuter quotidiennement à 20 heures, je devrais attendre jusqu'à 20 heures pour que la fonction s'exécute réellement sur ma machine.
Donc ma question est: Quelle est la façon la plus simple et la meilleure de faire exécuter une fonction localement une fois?
Choses que j'ai essayées ou envisagées:
Run()
de la fonction TimerInfo
et TraceWriter
à Run()
- et j'ai trouvé étonnamment peu de documentation pour cela.La page Stratégies pour tester votre code dans Azure Functions de Microsoft n'est pas très utile sur ce sujet - elle mentionne uniquement les déclencheurs de minuterie comme moyen de tester les types de déclencheurs autre.
Dans un monde parfait, je toucherais F5 et la fonction s'exécuterait immédiatement une fois - tout comme le développement d'une application .NET "normale".
Vous pouvez peut-être utiliser l'indicateur RunOnStartup
comme indiqué ici . Il ne répond pas tout à fait à votre mémoire concernant le fait qu'il ne fonctionne qu'une seule fois, mais il devrait au moins l'exécuter localement une fois que l'application a démarré.
/// 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.
Exemple utilisant la liaison d'attribut:
[TimerTrigger("%TimerSchedule%", RunOnStartup = true)]TimerInfo myTimer
J'ai eu la même question et utilisé le drapeau DEBUG pour avoir RunOnStartup uniquement lors du débogage:
public static void Run(
[TimerTrigger("* 0 7 * * 1-5"
#if DEBUG
, RunOnStartup=true
#endif
)]TimerInfo myTimer, TraceWriter log)
{
J'avais la même question. Je l'ai réparé avec un Unittest. En effet, vous devez supprimer le TraceWriter et le TimerInfo.
Voici un peu de code sur la façon dont j'ai fait cela.
TimerInfo:
public class ScheduleStub : TimerInfo
{
public ScheduleStub(TimerSchedule schedule, ScheduleStatus status, bool isPastDue = false) : base(schedule, status, isPastDue)
{
}
}
Et le 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;
}
Ajoutez simplement une autre fonction avec le type de déclencheur HTTP dans la même classe, ajoutez votre code ou appelez votre méthode Run à partir de cette fonction et appelez-la à partir de votre navigateur.
Assurez-vous de commenter/supprimer cette fonction lors du déploiement sur prod, ou vous aurez la possibilité de déclencher la fonction via des appels HTTP dans prod.