教程:开发适用于 Windows 设备的 C# IoT Edge 模块Tutorial: Develop a C# IoT Edge module for Windows devices

使用 Visual Studio 开发 C# 代码并将其部署到运行 Azure IoT Edge 的 Windows 设备。Use Visual Studio to develop C# code and deploy it to a Windows device running Azure IoT Edge.

可以使用 Azure IoT Edge 模块部署代码,直接将业务逻辑实现到 IoT Edge 设备。You can use Azure IoT Edge modules to deploy code that implements your business logic directly to your IoT Edge devices. 本教程详细介绍如何创建并部署用于筛选传感器数据的 IoT Edge 模块。This tutorial walks you through creating and deploying an IoT Edge module that filters sensor data. 本教程介绍如何执行下列操作:In this tutorial, you learn how to:

  • 使用 Visual Studio 创建基于 C# SDK 的 IoT Edge 模块。Use Visual Studio to create an IoT Edge module that's based on the C# SDK.
  • 使用 Visual Studio 和 Docker 创建 Docker 映像并将其发布到注册表。Use Visual Studio and Docker to create a Docker image and publish it to your registry.
  • 将模块部署到 IoT Edge 设备。Deploy the module to your IoT Edge device.
  • 查看生成的数据。View generated data.

在本教程中创建的 IoT Edge 模块可以筛选由设备生成的温度数据。The IoT Edge module that you create in this tutorial filters the temperature data that's generated by your device. 它只在温度高于指定阈值的情况下,向上游发送消息。It only sends messages upstream if the temperature is above a specified threshold. 在边缘进行的此类分析适用于减少传递到云中和存储在云中的数据量。This type of analysis at the edge is useful for reducing the amount of data that's communicated to and stored in the cloud.

如果没有 Azure 订阅,可在开始前创建一个试用帐户If you don't have an Azure subscription, create a trial account before you begin.

解决方案范围Solution scope

本教程演示如何使用 Visual Studio 2019C# 开发模块,以及如何将其部署到 Windows 设备This tutorial demonstrates how to develop a module in C# using Visual Studio 2019, and how to deploy it to a Windows device. 若要开发适用于 Linux 设备的模块,请转到开发适用于 Linux 设备的 C# IoT Edge 模块If you're developing modules for Linux devices, go to Develop a C# IoT Edge module for Linux devices instead.

使用下表了解开发 C 模块并将其部署到 Windows 设备的选项:Use the following table to understand your options for developing and deploying C modules to Windows devices:

C#C# Visual Studio CodeVisual Studio Code Visual Studio 2017/2019Visual Studio 2017/2019
Windows AMD64 开发Windows AMD64 develop 在 VS Code 中开发 WinAMD64 的 C# 模块 在 Visual Studio 中开发 WinAMD64 的 C# 模块
Windows AMD64 调试Windows AMD64 debug 在 Visual Studio 中调试 WinAMD64 的 C# 模块

先决条件Prerequisites

在开始学习本教程之前,应已完成上一篇教程开发适用于 Windows 设备的 IoT Edge 模块来设置开发环境。Before beginning this tutorial, you should have gone through the previous tutorial to set up your development environment, Develop an IoT Edge module for a Windows device. 完成该教程后,已应准备好以下必备组件:After completing that tutorial, you already should have the following prerequisites:

Tip

如果使用的是 Visual Studio 2017(版本 15.7 或更高版本),请从 Visual Studio 市场下载并安装适用于 VS 2017 的 Azure IoT Edge ToolsIf you are using Visual Studio 2017 (version 15.7 or higher), plrease download and install Azure IoT Edge Tools for VS 2017 from the Visual Studio marketplace

创建模块项目Create a module project

以下步骤使用 Visual Studio 和 Azure IoT Edge Tools 扩展创建 IoT Edge 模块项目。The following steps create an IoT Edge module project by using Visual Studio and the Azure IoT Edge Tools extension. 创建项目模板后,请添加新代码,使模块根据其报告属性筛选出消息。Once you have a project template created, add new code so that the module filters out messages based on their reported properties.

创建新项目Create a new project

Azure IoT Edge Tools 为 Visual Studio 中支持的所有 IoT Edge 模块语言提供项目模板。The Azure IoT Edge Tools provides project templates for all supported IoT Edge module languages in Visual Studio. 这些模板包含将工作模块部署到测试 IoT Edge 所需的所有文件和代码,或者提供一个起点让你使用自己的业务逻辑自定义模板。These templates have all the files and code that you need to deploy a working module to test IoT Edge, or give you a starting point to customize the template with your own business logic.

  1. 启动 Visual Studio 2019 并选择“创建新项目” 。Launch Visual Studio 2019 and select Create New Project.

  2. 在“新建项目”窗口中,搜索“IoT Edge” 项目,然后选择“Azure IoT Edge (Windows amd64)” 项目。In the new project window, search IoT Edge project and choose the Azure IoT Edge (Windows amd64) project. 单击“下一步” 。Click Next.

    创建新的 Azure IoT Edge 项目

  3. 在“配置新项目”窗口中,重命名项目和解决方案,使名称具有描述性,例如 CSharpTutorialAppIn the configure your new project window, rename the project and solution to something descriptive like CSharpTutorialApp. 单击“创建”以创建项目。 Click Create to create the project.

    配置新的 Azure IoT Edge 项目

  4. 在 IoT Edge 应用程序和模块窗口中,使用以下值配置项目:In the IoT Edge application and module window, configure your project with the following values:

    字段Field ValueValue
    选择模板Select a template 选择“C# 模块”。 Select C# Module.
    模块项目名称Module project name 将模块命名为 CSharpModuleName your module CSharpModule.
    Docker 映像存储库Docker image repository 映像存储库包含容器注册表的名称和容器映像的名称。An image repository includes the name of your container registry and the name of your container image. 系统已基于模块项目名称值预先填充容器映像。Your container image is prepopulated from the module project name value. localhost:5000 替换为 Azure 容器注册表中的登录服务器值。Replace localhost:5000 with the login server value from your Azure container registry. 可以在 Azure 门户的容器注册表的“概览”页中检索登录服务器。You can retrieve the login server from the Overview page of your container registry in the Azure portal.

    最终的映像存储库看起来类似于 <registry name>.azurecr.cn/csharpmodule。The final image repository looks like <registry name>.azurecr.cn/csharpmodule.

    配置目标设备、模块类型和容器注册表的项目

  5. 选择“确定”以应用更改。 Select OK to apply your changes.

添加注册表凭据Add your registry credentials

部署清单与 IoT Edge 运行时共享容器注册表的凭据。The deployment manifest shares the credentials for your container registry with the IoT Edge runtime. 此运行时需要这些凭据才能将专用映像拉取到 IoT Edge 设备中。The runtime needs these credentials to pull your private images onto the IoT Edge device. 使用 Azure 容器注册表的“访问密钥”部分提供的凭据。 Use the credentials from the Access keys section of your Azure container registry.

  1. 在 Visual Studio 解决方案资源管理器中打开 deployment.template.json 文件。In the Visual Studio solution explorer, open the deployment.template.json file.

  2. 在 $edgeAgent 所需属性中找到 registryCredentials 属性。Find the registryCredentials property in the $edgeAgent desired properties.

  3. 使用你的凭据用以下格式更新该属性:Update the property with your credentials, following this format:

    "registryCredentials": {
      "<registry name>": {
        "username": "<username>",
        "password": "<password>",
        "address": "<registry name>.azurecr.cn"
      }
    }
    
  4. 保存 deployment.template.json 文件。Save the deployment.template.json file.

使用自定义代码更新模块Update the module with custom code

默认模块代码接收输入队列中的消息,然后通过输出队列传递这些消息。The default module code receives messages on an input queue and passes them along through an output queue. 让我们添加一些附加的代码,使模块在将消息转发到 IoT 中心之前,先在边缘上对其进行处理。Let's add some additional code so that the module processes the messages at the edge before forwarding them to IoT Hub. 更新模块,使其分析每条消息中的温度数据,并仅在温度超过特定的阈值时,才将消息发送到 IoT 中心。Update the module so that it analyzes the temperature data in each message, and only sends the message to IoT Hub if the temperature exceeds a certain threshold.

  1. 在 Visual Studio 中,打开“CSharpModule” > “Program.cs” 。In Visual Studio, open CSharpModule > Program.cs.

  2. CSharpModule 命名空间的顶部,为稍后要使用的类型添加三个 using 语句:At the top of the CSharpModule namespace, add three using statements for types that are used later:

    using System.Collections.Generic;     // For KeyValuePair<>
    using Microsoft.Azure.Devices.Shared; // For TwinCollection
    using Newtonsoft.Json;                // For JsonConvert
    
  3. temperatureThreshold 变量添加到 counter 变量后面的 Program 类中。Add the temperatureThreshold variable to the Program class after the counter variable. temperatureThreshold 变量设置一个值,若要向 IoT 中心发送数据,测量的温度必须超出该值。The temperatureThreshold variable sets the value that the measured temperature must exceed for the data to be sent to the IoT hub.

    static int temperatureThreshold { get; set; } = 25;
    
  4. MessageBodyMachineAmbient 类添加到变量声明后面的 Program 类中。Add the MessageBody, Machine, and Ambient classes to the Program class after the variable declarations. 这些类将为传入消息的正文定义所需的架构。These classes define the expected schema for the body of incoming messages.

    class MessageBody
    {
        public Machine machine {get;set;}
        public Ambient ambient {get; set;}
        public string timeCreated {get; set;}
    }
    class Machine
    {
        public double temperature {get; set;}
        public double pressure {get; set;}         
    }
    class Ambient
    {
        public double temperature {get; set;}
        public int humidity {get; set;}         
    }
    
  5. 查找 Init 方法。Find the Init method. 此方法创建并配置 ModuleClient 对象,使模块能够连接到本地 Azure IoT Edge 运行时以发送和接收消息。This method creates and configures a ModuleClient object, which allows the module to connect to the local Azure IoT Edge runtime to send and receive messages. 代码还会注册一个回调,以通过 input1 终结点从 IoT Edge 中心接收消息。The code also registers a callback to receive messages from an IoT Edge hub via the input1 endpoint.

    将整个 Init 方法替换为以下代码:Replace the entire Init method with the following code:

    static async Task Init()
    {
        AmqpTransportSettings amqpSetting = new AmqpTransportSettings(TransportType.Amqp_Tcp_Only);
        ITransportSettings[] settings = { amqpSetting };
    
        // Open a connection to the Edge runtime
        ModuleClient ioTHubModuleClient = await ModuleClient.CreateFromEnvironmentAsync(settings);
        await ioTHubModuleClient.OpenAsync();
        Console.WriteLine("IoT Hub module client initialized.");
    
        // Read the TemperatureThreshold value from the module twin's desired properties
        var moduleTwin = await ioTHubModuleClient.GetTwinAsync();
        await OnDesiredPropertiesUpdate(moduleTwin.Properties.Desired, ioTHubModuleClient);
    
        // Attach a callback for updates to the module twin's desired properties.
        await ioTHubModuleClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertiesUpdate, null);
    
        // Register a callback for messages that are received by the module.
        await ioTHubModuleClient.SetInputMessageHandlerAsync("input1", FilterMessages, ioTHubModuleClient);
    }
    

    更新的此 Init 方法仍使用 ModuleClient 来与 IoT Edge 运行时建立连接,但同时添加了新的功能。This updated Init method still sets up the connection to the IoT Edge runtime with the ModuleClient, but also adds new functionality. 它读取模块孪生的所需属性,以检索 temperatureThreshold 值。It reads the module twin's desired properties to retrieve the temperatureThreshold value. 然后,它创建一个回调用于侦听将来对模块孪生所需属性做出的任何更新。Then, it creates a callback that listens for any future updates to the module twin's desired properties. 使用此回调可以远程更新模块孪生中的温度阈值,而更改将合并到模块中。With this callback, you can update the temperature threshold in the module twin remotely, and the changes will be incorporated into the module.

    更新的 Init 方法还会更改现有的 SetInputMessageHandlerAsync 方法。The updated Init method also changes the existing SetInputMessageHandlerAsync method. 在示例代码中,input1 上的传入消息将使用 PipeMessage 函数进行处理,但我们想要改用将在以下步骤中创建的 FilterMessages 函数。In the sample code, incoming messages on input1 are processed with the PipeMessage function, but we want to change that to use the FilterMessages function that we'll create in the following steps.

  6. 将新的 onDesiredPropertiesUpdate 方法添加到 Program 类。Add a new onDesiredPropertiesUpdate method to the Program class. 此方法从孪生模块接收所需属性的更新,然后更新 temperatureThreshold 变量,使之匹配。This method receives updates on the desired properties from the module twin, and updates the temperatureThreshold variable to match. 所有模块都有自己的孪生模块,因此可以直接从云配置在模块中运行的代码。All modules have their own module twin, which lets you configure the code that's running inside a module directly from the cloud.

    static Task OnDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext)
    {
        try
        {
            Console.WriteLine("Desired property change:");
            Console.WriteLine(JsonConvert.SerializeObject(desiredProperties));
    
            if (desiredProperties["TemperatureThreshold"]!=null)
                temperatureThreshold = desiredProperties["TemperatureThreshold"];
    
        }
        catch (AggregateException ex)
        {
            foreach (Exception exception in ex.InnerExceptions)
            {
                Console.WriteLine();
                Console.WriteLine("Error when receiving desired property: {0}", exception);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine("Error when receiving desired property: {0}", ex.Message);
        }
        return Task.CompletedTask;
    }
    
  7. 删除示例 PipeMessage 方法,并将其替换为新的 FilterMessages 方法。Remove the sample PipeMessage method and replace it with a new FilterMessages method. 每当模块从 IoT Edge 中心接收消息,就会调用此方法。This method is called whenever the module receives a message from the IoT Edge hub. 此方法筛选掉那些所报告温度低于温度阈值(通过孪生模块进行设置)的消息。It filters out messages that report temperatures below the temperature threshold set via the module twin. 它还将 MessageType 属性添加到消息,其值设置为“警报”。 It also adds the MessageType property to the message with the value set to Alert.

    static async Task<MessageResponse> FilterMessages(Message message, object userContext)
    {
        var counterValue = Interlocked.Increment(ref counter);
        try
        {
            ModuleClient moduleClient = (ModuleClient)userContext;
            var messageBytes = message.GetBytes();
            var messageString = Encoding.UTF8.GetString(messageBytes);
            Console.WriteLine($"Received message {counterValue}: [{messageString}]");
    
            // Get the message body.
            var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
    
            if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
            {
                Console.WriteLine($"Machine temperature {messageBody.machine.temperature} " +
                    $"exceeds threshold {temperatureThreshold}");
                var filteredMessage = new Message(messageBytes);
                foreach (KeyValuePair<string, string> prop in message.Properties)
                {
                    filteredMessage.Properties.Add(prop.Key, prop.Value);
                }
    
                filteredMessage.Properties.Add("MessageType", "Alert");
                await moduleClient.SendEventAsync("output1", filteredMessage);
            }
    
            // Indicate that the message treatment is completed.
            return MessageResponse.Completed;
        }
        catch (AggregateException ex)
        {
            foreach (Exception exception in ex.InnerExceptions)
            {
                Console.WriteLine();
                Console.WriteLine("Error in sample: {0}", exception);
            }
            // Indicate that the message treatment is not completed.
            var moduleClient = (ModuleClient)userContext;
            return MessageResponse.Abandoned;
        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine("Error in sample: {0}", ex.Message);
            // Indicate that the message treatment is not completed.
            ModuleClient moduleClient = (ModuleClient)userContext;
            return MessageResponse.Abandoned;
        }
    }
    
  8. 保存 Program.cs 文件。Save the Program.cs file.

  9. 在 IoT Edge 解决方案中打开 deployment.template.json 文件。Open the deployment.template.json file in your IoT Edge solution. 此文件告知 IoT Edge 代理部署哪些模块(在本例中为 SimulatedTemperatureSensorCSharpModule),并告知 IoT Edge 中心如何在它们之间路由消息。This file tells the IoT Edge agent which modules to deploy, in this case SimulatedTemperatureSensor and CSharpModule, and tells the IoT Edge hub how to route messages between them.

  10. CSharpModule 模块孪生添加到部署清单。Add the CSharpModule module twin to the deployment manifest. modulesContent 节底部的 $edgeHub 模块孪生后面插入以下 JSON 内容:Insert the following JSON content at the bottom of the modulesContent section, after the $edgeHub module twin:

       "CSharpModule": {
           "properties.desired":{
               "TemperatureThreshold":25
           }
       }
    

    将模块孪生添加到部署模板

  11. 保存 deployment.template.json 文件。Save the deployment.template.json file.

生成并推送模块Build and push your module

在上一部分,你已经创建了一个 IoT Edge 解决方案并将代码添加到了 CSharpModule,该函数会筛选出其中报告的计算机温度低于可接受阈值的消息。In the previous section, you created an IoT Edge solution and added code to the CSharpModule to filter out messages where the reported machine temperature is below the acceptable threshold. 现在需将解决方案生成为容器映像并将其推送到容器注册表。Now you need to build the solution as a container image and push it to your container registry.

  1. 在开发计算机上使用以下命令登录到 Docker。Use the following command to sign in to Docker on your development machine. 使用 Azure 容器注册表中的用户名、密码和登录服务器。Use the username, password, and login server from your Azure container registry. 可以在 Azure 门户中从注册表的“访问密钥”部分检索这些值。 You can retrieve these values from the Access keys section of your registry in the Azure portal.

    docker login -u <ACR username> -p <ACR password> <ACR login server>
    

    可能会出现一条安全警告,其中建议使用 --password-stdinYou may receive a security warning recommending the use of --password-stdin. 这条最佳做法是针对生产场景建议的,这超出了本教程的范畴。While that best practice is recommended for production scenarios, it's outside the scope of this tutorial. 有关详细信息,请参阅 docker login 参考。For more information, see the docker login reference.

  2. 在 Visual Studio 解决方案资源管理器中,右键单击要生成的项目名称。In the Visual Studio solution explorer, right-click the project name that you want to build. 默认名称为 AzureIotEdgeApp1;由于生成的是 Windows 模块,因此扩展名应是 Windows.Amd64The default name is AzureIotEdgeApp1 and since you're building a Windows module, the extension should be Windows.Amd64.

  3. 选择“生成并推送 IoT Edge 模块”。 Select Build and Push IoT Edge Modules.

    “生成并推送”命令会启动三项操作。The build and push command starts three operations. 首先,它在解决方案中创建名为 config 的新文件夹,用于保存基于部署模板和其他解决方案文件中的信息生成的完整部署清单。First, it creates a new folder in the solution called config that holds the full deployment manifest, built out of information in the deployment template and other solution files. 其次,它会运行 docker build,以基于目标体系结构的相应 dockerfile 生成容器映像。Second, it runs docker build to build the container image based on the appropriate dockerfile for your target architecture. 然后,它会运行 docker push,以将映像存储库推送到容器注册表。Then, it runs docker push to push the image repository to your container registry.

将模块部署到设备Deploy modules to device

使用 Visual Studio Cloud Explorer 和 Azure IoT Edge Tools 扩展将模块项目部署到 IoT Edge 设备。Use the Visual Studio cloud explorer and the Azure IoT Edge Tools extension to deploy the module project to your IoT Edge device. 你已经为方案准备了部署清单,即 config 文件夹中的 deployment.json 文件。You already have a deployment manifest prepared for your scenario, the deployment.json file in the config folder. 现在需要做的就是选择一个设备来接收部署。All you need to do now is select a device to receive the deployment.

请确保 IoT Edge 设备已启动并正在运行。Make sure that your IoT Edge device is up and running.

  1. 在 Visual Studio Cloud Explorer 中,展开资源以查看 IoT 设备列表。In the Visual Studio cloud explorer, expand the resources to see your list of IoT devices.

  2. 右键单击要接收部署的 IoT Edge 设备的名称。Right-click the name of the IoT Edge device that you want to receive the deployment.

  3. 选择“创建部署”。 Select Create Deployment.

  4. 在文件资源管理器中,选择解决方案的 config 文件夹中的 deployment.windows-amd64 文件。In the file explorer, select the deployment.windows-amd64 file in the config folder of your solution.

  5. 刷新 Cloud Explorer,以查看设备下面列出的已部署模块。Refresh the cloud explorer to see the deployed modules listed under your device.

查看生成的数据View generated data

将部署清单应用到 IoT Edge 设备以后,设备上的 IoT Edge 运行时就会收集新的部署信息并开始在其上执行操作。Once you apply the deployment manifest to your IoT Edge device, the IoT Edge runtime on the device collects the new deployment information and starts executing on it. 在设备上运行的未包括在部署清单中的任何模块都会停止。Any modules running on the device that aren't included in the deployment manifest are stopped. 设备中缺失的任何模块都会启动。Any modules missing from the device are started.

可以使用 IoT Edge Tools 扩展查看抵达 IoT 中心的消息。You can use the IoT Edge Tools extension to view messages as they arrive at your IoT Hub.

  1. 在 Visual Studio Cloud Explorer 中,选择 IoT Edge 设备的名称。In the Visual Studio cloud explorer, select the name of your IoT Edge device.

  2. 在“操作”列表中,选择“开始监视内置事件终结点”。 In the Actions list, select Start Monitoring Built-in Event Endpoint.

  3. 查看抵达 IoT 中心的消息。View the messages arriving at your IoT Hub. 消息可能需要在一段时间后才会抵达,因为在发送消息之前,对 CSharpModule 代码所做的更改需要等到机器温度达到 25 度才会生效。It may take a while for the messages to arrive, because the changes we made to the CSharpModule code wait until the machine temperature reaches 25 degrees before sending messages. IoT 中心还会将消息类型“警报”添加到达到该温度阈值的任何消息。 It also adds the message type Alert to any messages that reach that temperature threshold.

    查看抵达 IoT 中心的消息

编辑模块孪生Edit the module twin

我们已使用 CSharpModule 模块孪生将温度阈值设置为 25 度。We used the CSharpModule module twin to set the temperature threshold at 25 degrees. 可以使用模块孪生来更改功能,而无需更新模块代码。You can use the module twin to change the functionality without having to update the module code.

  1. 在 Visual Studio 中打开 deployment.windows-amd64.json 文件。In Visual Studio, open the deployment.windows-amd64.json file. (不是 deployment.template 文件。(Not the deployment.template file. 如果在解决方案资源管理器中的 config 文件内未看到部署清单,请在 Cloud Explorer 工具栏中选择“显示所有文件”图标。) If you don't see the deployment manifest in the config file in the solution explorer, select the Show all files icon in the explorer toolbar.)

  2. 找到 CSharpModule 孪生,将 temperatureThreshold 参数的值更改为比上次报告的温度高出 5 到 10 度的新温度。Find the CSharpModule twin and change the value of the temperatureThreshold parameter to a new temperature 5 degrees to 10 degrees higher than the latest reported temperature.

  3. 保存 deployment.windows-amd64.json 文件。Save the deployment.windows-amd64.json file.

  4. 再次遵循部署步骤,将更新的部署清单应用到设备。Follow the deployment steps again to apply the updated deployment manifest to your device.

  5. 监视传入的设备到云消息。Monitor the incoming device-to-cloud messages. 应会看到,在达到新的温度阈值之前,消息会停止发送。You should see the messages stop until the new temperature threshold is reached.

清理资源Clean up resources

如果打算继续学习下一篇建议的文章,可以保留已创建的资源和配置,以便重复使用。If you plan to continue to the next recommended article, you can keep the resources and configurations that you created and reuse them. 还可以继续使用相同的 IoT Edge 设备作为测试设备。You can also keep using the same IoT Edge device as a test device.

否则,可以删除本文中使用的本地配置和 Azure 资源,以免产生费用。Otherwise, you can delete the local configurations and the Azure resources that you used in this article to avoid charges.

删除 Azure 资源Delete Azure resources

删除 Azure 资源和资源组的操作不可逆。Deleting Azure resources and resource groups is irreversible. 请确保不要意外删除错误的资源组或资源。Make sure that you don't accidentally delete the wrong resource group or resources. 如果在现有的包含要保留资源的资源组中创建了 IoT 中心,请只删除 IoT 中心资源本身,而不要删除资源组。If you created the IoT hub inside an existing resource group that has resources that you want to keep, delete only the IoT hub resource itself, instead of deleting the resource group.

若要删除资源,请执行以下操作:To delete the resources:

  1. 登录到 Azure 门户,然后选择“资源组”。Sign in to the Azure portal and select Resource groups.

  2. 选择包含 IoT Edge 测试资源的资源组的名称。Select the name of the resource group that contains your IoT Edge test resources.

  3. 查看包含在资源组中的资源的列表。Review the list of resources contained in your resource group. 若要删除这一切,可以选择“删除资源组”。If you want to delete all of them, you can select Delete resource group. 如果只需删除部分内容,可以单击要单独删除的每个资源。If you want to delete only some of them, you can click into each resource to delete them individually.

后续步骤Next steps

在本教程中,你已创建一个 IoT Edge 模块,其中包含用于筛选 IoT Edge 设备生成的原始数据的代码。In this tutorial, you created an IoT Edge module with code to filter raw data that's generated by your IoT Edge device. 准备好生成自己的模块时,可以详细了解如何开发自己的 IoT Edge 模块或如何使用 Visual Studio 开发模块When you're ready to build your own modules, you can learn more about developing your own IoT Edge modules or how to develop modules with Visual Studio. 可以继续学习后续教程,了解 Azure IoT Edge 如何帮助你部署 Azure 云服务,以在边缘位置处理和分析数据。You can continue on to the next tutorials to learn how Azure IoT Edge can help you deploy Azure cloud services to process and analyze data at the edge.