65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Visual Studio 开发 Azure Function

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2017 年 5 月 6 日

CPOL

6分钟阅读

viewsIcon

13039

介绍如何使用 Azure WebJob SDK 开发 Azure 函数的脚本。

引言

Azure Function 是一个服务,它将 Azure App Service 中包含的 Azure Web Job 功能分离出来,形成独立的产品。遗憾的是,Visual Studio 中丰富的 IDE 支持尚未提供。此外,Microsoft Docs 中发布的方法还提到间接使用 Azure Function 设置或利用 Node 的 CLI。

我的意图是使用 Visual Studio 的控制台项目和 Azure 存储模拟器。这是关于开发和测试 C# Azure Function,将其作为一个普通的 C# 编译器项目,而不是 C# 脚本,然后将其迁移到 C# Azure Function。如果您购买并使用 LINQPAD 高级版本,您也可以在 LINQPAD 中完成同样的操作,这样您就可以更积极地开发 Azure Function。

入门

由于 Azure Function 基于 Azure Web Job,Azure Function 与最初为 .NET 发布 Web Job SDK 之间存在一定的兼容性。换句话说,与其用 C# 脚本编写新东西,不如说 Azure Function 的本质是打包了您现有的 SDK 以供 C# 脚本使用。不幸的是,它并不是完全相同的代码库,但由于兼容性,能够做到这一点是其优点之一,这也是其中一部分。

首先,请检查是否已安装以下软件栈

  • Azure 存储模拟器(包含在 Azure Cloud Service SDK 中)
  • Visual Studio 2015 或更高版本
  • .NET Framework 4.6 或更高版本

如果您的环境不是 Windows 开发环境,则不提供 Azure 存储模拟器。在这种情况下,您将不可避免地需要创建并连接实际的 Azure 存储帐户。对于 IDE,您可以改用 Visual Studio Code、Visual Studio for Mac 或 Rider。您还可以安装 Mono 来进行开发。不幸的是,截至 2017 年 4 月,.NET Core 尚不支持。

使用您喜欢的 IDE 创建一个控制台项目,然后安装以下 NuGet 包

  • Microsoft.Azure.WebJobs (2.0.0+)
  • Microsoft.Azure.WebJobs.Extensions (2.0.0+)

Using the Code

然后像这样编写 Main 方法

var jobHostConfig = new JobHostConfiguration("UseDevelopmentStorage=true");
jobHostConfig.UseCore();
jobHostConfig.UseFiles();
jobHostConfig.UseTimers();
jobHostConfig.UseDevelopmentSettings();

using (var cts = new CancellationTokenSource())
using (var jobHost = new JobHost(jobHostConfig))
{
    jobHost.StartAsync(cts.Token);
    Console.WriteLine("Press Ctrl + C to stop the service.");
    Console.CancelKeyPress += (s, e) => cts.Cancel();
    cts.Token.WaitHandle.WaitOne(Timeout.Infinite);
}

 

在可以使用本地 Azure 存储模拟器的 Windows 环境中,指定“UseDevelopmentStorage=true”连接字符串。在其他环境中,必须在属性窗格中找到并分配实际 Azure 存储帐户的连接字符串。

然后,像这样编写要在 Azure Function 中托管的函数

public static void Run(
    [TimerTrigger("* * * * * *", UseMonitor = true)]
    TimerInfo myTimer,
    TraceWriter log)
{
    log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
}

请注意,TimerTrigger 指定在 TimerInfo 方法参数中。TimerTrigger 的第一个参数表示计时器的运行间隔。建议您学习语法,因为通过引用 Crontab 中使用的重复间隔显示语法来配置指定值,可以方便地迁移到 Azure Function。

要检查它是否运行正常,请启动 Azure 存储模拟器并按 F5 运行示例程序。如果输出与以下类似,则表示正常。

Press Ctrl + C to stop the service.
Development settings applied
Found the following functions:
TimerSample.Run
Singleton lock acquired (1ce1ebaf1e584866b90488a9e1b5d19f/TimerSample.Run.Listener)
The next 5 occurrences of the schedule will be:
2017-04-24 AM 12:16:59
2017-04-24 AM 12:17:00
2017-04-24 AM 12:17:01
2017-04-24 AM 12:17:02
2017-04-24 AM 12:17:03
Job host started
Executing 'TimerSample.Run' (Reason='Timer fired at 2017-04-24T00:16:59.0273081+09:00', Id=aa02dc0a-5a89-4ebd-bf08-8182cce53a0c)
C# Timer trigger function executed at: 2017-04-24 AM 12:16:59
Executed 'TimerSample.Run' (Succeeded, Id=aa02dc0a-5a89-4ebd-bf08-8182cce53a0c)
Executing 'TimerSample.Run' (Reason='Timer fired at 2017-04-24T00:17:00.0061625+09:00', Id=f8161e5d-c989-4d2d-9a49-cb5d9d269134)
C# Timer trigger function executed at: 2017-04-24 AM 12:17:00
Executed 'TimerSample.Run' (Succeeded, Id=f8161e5d-c989-4d2d-9a49-cb5d9d269134)

Migration

有一个有用的服务可以用来检查此 Azure Function 是否真的运行正常。尝试 Azure App Service,它允许您除了 Microsoft 帐户外,还可以使用 Google (GMAIL)、Facebook 或 Github 帐户登录,即可获得一个小时的试用 Azure Function 帐户,而无需实际的 Microsoft Azure 订阅。

访问 https://azure.microsoft.com/en-us/try/app-service/ 创建新帐户。

接下来,复制上面 Run 方法的代码。但是,在复制之前,有几部分需要更正或确认。

  • 您必须指定对开发过程中引用的 NuGet 包的引用。project.json 文件默认不会创建,因此您需要创建以下骨架,并将当前正在开发的项目的 package.config 文件内容复制进去。除了根据依赖项自动安装的包之外,您可以仅指定您实际添加的那些包。
{
  "frameworks": {
    "net46":{
      "dependencies": {
        "Microsoft.ProjectOxford.Face": "1.1.0"
      }
    }
   }
}
  • 如果您引用的是 BCL 中的程序集或单个 .NET DLL 文件,而不是 NuGet 包,请使用 C# 脚本特有的 #r 指令来指定引用。
    • 安装在 GAC 中或手动单独引用的 .NET DLL 文件必须直接上传到 bin 文件夹。
    • 如果 DLL 是专门为 x86 构建的,或者在准备和使用过程中需要执行系统注册表更改等操作,则无法使用。
  • 在移动函数之前,请检查方法名称和签名是否与首次创建 Azure Function 时相同。如果运行不正常,请参考 function.json 文件。
    {
      "disabled": false,
      "bindings": [
        {
          "name": "myTimer",
          "type": "timerTrigger",
          "direction": "in",
          "schedule": "0 */5 * * * *"
        }
      ]
    }
  • 最后,检查触发器(如 TimerTriggerBlobTriggerServiceBusTrigger)中指定的参数值,并修改 function.json 文件。在上面的示例中,我们将其设置为每秒运行一次,因此我们需要将 function.json 的 schedule 属性更改为“* * * * * *”。

总结

您可以自由分发最终的 CSX 文件,该文件是实际 Azure Function 服务的结果。对于持续开发,将其设置为通过版本控制存储库分发可能会更方便。

在撰写本文时,我认为还有一些我可能稍微担心的事情

  • HTTP Trigger 和 Web Hook Trigger 与 Web Jobs 没有直接关系,更像是 ASP.NET Web API 的一个子集。只有使用 TraceWriter 类的部分与 Web Job 完全相关。在这方面,似乎可以创建一个 DummyTraceWriter 类来进行单元测试。
    class DummyTraceWriter : TraceWriter
    {
        public DummyTraceWriter() : base(default(TraceLevel)) { }
        public override void Trace(TraceEvent traceEvent) => Console.WriteLine(traceEvent);
    }
  • 如果您为 LINQPAD 创建并共享脚本模板,我认为在完整 SDK 发布之前,您将能够开发和测试更多的 Azure Function。
  • 包含一些本机代码的 NuGet 包可能期望使用为 64 位构建的包在执行时不会有问题。如果 32 位版本的包也作为单独的 EXE 文件运行,Windows-on-Windows 兼容性功能将确保执行。

HTTP 触发器的补充

HTTP Trigger 是 Function 中特有的一个功能。它不同于现有的基于 Web Job 的开发方法。它被提供为一个输出函数,等待 HTTP 请求并返回 HTTP 响应。不幸的是,Azure Function 只支持 HTTP 响应的输出,截至 2017 年 5 月,它不支持从其他地方调用 Web Invocation 的输出。

本文介绍的方法是关于与多个 Azure 组件间接调用函数相关的触发器的本地开发。

如果您需要基于可以直接调用的 HTTP 触发器进行开发,而不是以 Web Jobs 的形式,建议参考 Justin Yoo 的文章,将 Azure Function App 开发为 ASP.NET Web 项目并将其发布到 Function App。

有关更多信息,请访问 http://blog.aliencube.org/en/2017/04/30/precompiled-azure-functions-revisited/
如果您能提供更多细节、需要补充的部分或需要修正的部分,那将非常有帮助。

历史

  • 2017 年 5 月 6 日 - 初版
© . All rights reserved.