在本地运行一次定时器触发的Azure功能的最简单方法是什么?

rip*_*ey_ 40 c# timer azure azure-functions

我有几个C#Azure函数使用计时器触发器按计划运行.我已经设置了它们,在%TimerSchedule%应用程序设置中指的是cron表达式:

public static void Run([TimerTrigger("%TimerSchedule%")]TimerInfo myTimer, TraceWriter log)
Run Code Online (Sandbox Code Playgroud)

在开发过程中,我经常希望使用Azure功能工具为Visual Studio + Azure功能核心工具在本地运行这些功能.但是,当我按F5调试本地函数时,它(通常)不会立即运行.相反,它根据计时器计划开始等待下一次出现.因此,例如,如果我的cron表达式表示每天晚上8点运行,我必须等到晚上8点才能在我的机器上实际运行该功能.

所以我的问题是:在本地运行一次函数的最简单和最好的方法什么?

我尝试或考虑过的事情:

  1. 使用更频繁的计时器计划仅用于本地开发
    • 这是好的,但并不完美 - 除非它非常频繁,否则你还需要等待一段时间,如果非常频繁,那么该函数可能会运行多次.这就是我现在正在做的事情.
  2. 编写一个直接调用函数Run()方法 的控制台应用程序或单元测试
    • 这不是100%直截了当,因为你必须提供TimerInfoTraceWriter参数Run()- 而且我发现了很少的文档.

Microsoft 在Azure功能页面中测试代码策略对此主题没有太大帮助 - 它只提到计时器触发器作为测试其他触发器类型的方法.

在一个完美的世界里,我会点击F5并且该功能会立即运行一次 - 就像开发一个"普通"的.NET应用程序一样.

Wah*_*uen 60

您也许可以使用此处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.
Run Code Online (Sandbox Code Playgroud)

使用属性绑定的示例:

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

  • @ripley_是的,我相信你会是对的.一个选项可能是将布尔值绑定到配置中的变量,类似于绑定"TimerSchedule"的方式.从那里,您可以将本地开发设置为true,并将生产(或其他)环境设置为false,如您所见. (3认同)
  • 如何将RunOnStartup绑定到我的配置中定义的布尔值."%%"语法不适用于非字符串值. (2认同)

Nis*_*san 59

来自https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=windows%2Ccsharp%2Cbash#non-http-triggered-functions

非 HTTP 触发函数

对于除 HTTP 触发器和 webhook 之外的所有类型的功能,您可以通过调用管理端点在本地测试您的功能。在本地服务器上使用 HTTP POST 请求调用此端点会触发该函数。您可以选择将测试数据传递给 POST 请求正文中的执行。此功能类似于 Azure 门户中的“测试”选项卡。

您调用以下管理员端点来触发非 HTTP 函数:

http://localhost:{port}/admin/functions/{function_name}

要将测试数据传递给函数的管理员端点,您必须在 POST 请求消息的正文中提供数据。消息正文需要具有以下 JSON 格式:

{
    "input": "<trigger_input>"
}
Run Code Online (Sandbox Code Playgroud)

  • 我必须将 `application/json` 的 `Content-Type` 和 `{ "input": null }` 的正文添加到我的 Insomnia/Postman 请求中的 POST 中。 (4认同)
  • 这应该是公认的答案!启动时运行很危险,可能会花费您很多钱! (2认同)
  • 请注意,默认端口是:7071 (2认同)

小智 39

我有同样的问题,并且在调试时只使用了DEBUG-flag来运行RunOnStartup:

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

  • 它看起来很可怕,但这就是我需要的,而且它有效。 (4认同)
  • 这就是我最终所做的,是的,它很丑陋,但它适用于本地调试目的! (2认同)
  • 您可以将硬编码的“true”替换为在其他地方定义的常量,并在常量声明中使用“#if DEBUG”。这至少使您的 Run 方法签名看起来更干净一些。 (2认同)

Ren*_*sak 13

如果使用 VS Code,请使用Azure Functions 扩展

  1. 按 F5 进入调试模式,这将启动功能应用程序。
  2. 转到活动栏中的 Azure 图标。
  3. 在 下Local Project,找到要运行的函数,右键单击,然后选择“立即执行函数”。

查看此 MS快速入门指南


Ale*_*fel 7

使用这个curl命令启动你的函数

curl --request POST -H "Content-Type:application/json" --data '{"input":""}'  http://localhost:7071/admin/functions/{function_name}
Run Code Online (Sandbox Code Playgroud)

输入数据是必需的,没有输入数据将不会触发该功能。


max*_*pan 6

使用邮递员应该可以解决问题。按照以下步骤在本地运行或调试您的定时器触发器。

1 . 运行你的项目。

  1. 打开 Postman 并通过此 url http://localhost:{port}/admin/functions/{function_name}

  2. 确保使用带有 { "input": "" } 的 Json 主体的 POST 方法

  3. 按发送。

您应该收到 202 的响应。


Ste*_*nHa 5

我有同样的问题。我用 Unittest 修复了它。实际上,您需要删除 TraceWriter 和 TimerInfo。

这里有一些代码我是如何做到这一点的。

定时器信息:

public class ScheduleStub : TimerInfo
{
    public ScheduleStub(TimerSchedule schedule, ScheduleStatus status, bool isPastDue = false) : base(schedule, status, isPastDue)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

和 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;
}
Run Code Online (Sandbox Code Playgroud)


Tho*_*mas 5

另一种方法是从 Postman 手动触发该函数:
手动运行非 HTTP 触发的函数

POST /admin/functions/<function name> HTTP/1.1
Host: localhost:<port>
Content-Type: application/json

{}
Run Code Online (Sandbox Code Playgroud)

对我来说,它看起来像邮递员上名为timeTrigger 的函数Function1在此输入图像描述