【问题标题】:Function fails to bind to output parameter函数无法绑定到输出参数
【发布时间】:2018-03-22 19:41:13
【问题描述】:

我有一个带有 TimerTrigger 的 Azure 函数,它可以正常工作并产生 400,000 条服务总线主题消息。我目前正在使用服务总线 API 在我的函数中手动将消息推送到其中。我现在想用输出绑定替换该代码,这样可以简化事情。

public static class Function1
{
    [FunctionName("ExportProcessor")]
    public static async Task Run(
        [TimerTrigger("0 30 5 */1 * *", RunOnStartup = true)]TimerInfo myTimer, 
        ILogger logger, 
        [ServiceBus("new-movie-publish", EntityType = EntityType.Topic)]IAsyncCollector<string> output)
    {
        await output.AddAsync("Foo");
        await output.AddAsync("Bar");
    }
}

但问题是,当我运行此测试代码时,它会因以下错误而失败:

MicrosoftAzure.WebJobs.Host:索引方法“Function1.Run”出错。 Microsoft.Azure.WebJobs.Host:无法将参数“输出”绑定到类型 IAsyncCollector`1。 确保绑定支持参数类型。

reading the documentation 时,IAsyncCollector1` 是受支持的绑定。

更新为显示配置文件和依赖项。

这是我的 .csproj 文件:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <AzureFunctionsVersion>v2</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Dapper" Version="1.50.4" />
    <PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.0-beta4" />
    <PackageReference Include="Microsoft.Azure.WebJobs.ServiceBus" Version="3.0.0-beta4" />
    <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.9" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Properties\" />
  </ItemGroup>
</Project>

我的 host.json 文件:

{
  "logger": {
    "categoryFilter": {
      "defaultLevel": "Information",
      "categoryLevels": {
        "Host": "Information",
        "Function": "Information"
      }
    }
  }
}

和我的 local.settings.json 配置

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "...",
    "APPINSIGHTS_INSTRUMENTATIONKEY": "...",
    "ExportUrl": "...",
    "ExportUtcHour": 5,
    "DefaultConnection": "...",
    "NewMovieTopic": "new-movie-publish",
    "AzureWebJobsServiceBus": "..."
  }
}

当我使用此代码发布消息时,这些设置工作正常:

public class MoviePublisherConfig
{
    public MoviePublisherConfig()
    {
        this.AzureWebJobsServiceBus = Environment.GetEnvironmentVariable(nameof(AzureWebJobsServiceBus), EnvironmentVariableTarget.Process);
        this.NewMovieTopic= Environment.GetEnvironmentVariable(nameof(NewMovieTopic), EnvironmentVariableTarget.Process);
    }

    public string AzureWebJobsServiceBus { get; set; }
    public string NewMovieTopic { get; set; }
}

public class MoviePublisher
{
    private readonly MoviePublisherConfig config;
    private readonly ILogger logger;

    public MoviePublisher(MoviePublisherConfig config, ILogger logger)
    {
        this.config = config ?? throw new ArgumentNullException(nameof(config));
        this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task PublishMovies(Movie[] movies)
    {
        var topicClient = new TopicClient(config.AzureWebJobsServiceBus, config.NewMovieTopic);
        var pendingTasks = new List<Task>();

        for(int index = 0; index < movies.Length; index++)
        {
            string movieJson = JsonConvert.SerializeObject(movies[index]);
            byte[] messageBuffer = Encoding.UTF8.GetBytes(movieJson);
            var message = new Message(messageBuffer);

            Task sendTask = topicClient.SendAsync(message);
            pendingTasks.Add(sendTask);

            if (pendingTasks.Count >= 1000)
            {
                await Task.WhenAll(pendingTasks);
                this.logger.LogInformation($"Processed {pendingTasks.Count} new movies.");
                pendingTasks.Clear();
            }
        }
    }
}

我在这里做错了什么?

【问题讨论】:

  • 刚刚试用了您的代码,效果很好...您介意共享依赖项和版本吗?
  • 已更新以显示我的依赖项和配置。
  • 啊,v2...我认为服务总线尚未完全集成到测试版中。
  • 有解决办法吗?这是我尝试与 Service Bus 集成的第二项技术。 NodeJs 函数超时存在问题,因此移至 netstandard .net core。
  • 现在坚持使用完整的 v1/.NET 是一个安全的选择

标签: azure azure-functions azureservicebus azure-servicebus-topics


【解决方案1】:

截至今天(2018 年 3 月),对 Functions V2 的服务总线支持仍在“建设中”。它有点在那里,但需要应用一些魔法。

问题在于它已从默认绑定包中移出到扩展模型中,并且仍然很粗糙。

在github上查看以下问题:

Migrate ServiceBus Extension to .NET Core - 关闭,但看到 cmets

Build failure after installing ExtensionsMetadatGenerator into empty v2 app

工作版本还没有在 NuGet 中,但如果你真的需要,你可以在MyGet 中获得它,版本 3.0.0-beta4-11250。

其他选项包括坚持手动发送,或使用 V1 / .NET 完整版 Functions。

【讨论】:

    猜你喜欢
    • 2020-04-22
    • 2021-12-30
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    相关资源
    最近更新 更多