.net core 从后台服务启动服务总线客户端

.net core 从后台服务启动服务总线客户端,.net-core,azureservicebus,asp.net-core-hosted-services,.net Core,Azureservicebus,Asp.net Core Hosted Services,我有一个ServiceBusClient类,它创建一个QueueClient,用于侦听总线上的消息。我已经阅读了以下文章来建立这个模型: 我的ServiceBusClient类处理QueueClient如下所示: public class ServiceBusClient : IServiceBusClient { public ServiceBusClient(IEventService eventService, ServiceBusClientOptions options)

我有一个
ServiceBusClient
类,它创建一个
QueueClient
,用于侦听总线上的消息。我已经阅读了以下文章来建立这个模型:

我的
ServiceBusClient
类处理
QueueClient
如下所示:

public class ServiceBusClient : IServiceBusClient
{
    public ServiceBusClient(IEventService eventService, ServiceBusClientOptions options)
    {
        ...
        queueClient = new QueueClient(options.ConnectionString, options.QueueName);
    }

    public void Run()
    {
        RegisterOnMessageHandler();
    }

    private void RegisterOnMessageHandler()
    {
        ...
        queueClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);
    }

    private async Task ProcessMessagesAsync(Message message, CancellationToken token)
    {
        var eventMessage = EventMessage.FromMessage(message);

        await eventService.Write(eventMessage);

        if (!token.IsCancellationRequested)
        {
            await queueClient.CompleteAsync(message.SystemProperties.LockToken);
        }
    }

    private Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs)
    {
        // log errors
        ...

        return Task.CompletedTask;
    }  
}
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
    serviceBusClient.Run();

    while (!cancellationToken.IsCancellationRequested)
    {
        // empty loop to keep running for lifetime of pod       
    }
}
我希望通过
IHostedService
甚至扩展
BackgroundService
来启动。在我发现的示例中,工作经常在while循环中执行,这不适合我的场景,因为我只尝试运行单个命令

因此,我创建了一个超级简单的实现,如下所示:

public class ServiceBusClient : IServiceBusClient
{
    public ServiceBusClient(IEventService eventService, ServiceBusClientOptions options)
    {
        ...
        queueClient = new QueueClient(options.ConnectionString, options.QueueName);
    }

    public void Run()
    {
        RegisterOnMessageHandler();
    }

    private void RegisterOnMessageHandler()
    {
        ...
        queueClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);
    }

    private async Task ProcessMessagesAsync(Message message, CancellationToken token)
    {
        var eventMessage = EventMessage.FromMessage(message);

        await eventService.Write(eventMessage);

        if (!token.IsCancellationRequested)
        {
            await queueClient.CompleteAsync(message.SystemProperties.LockToken);
        }
    }

    private Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs)
    {
        // log errors
        ...

        return Task.CompletedTask;
    }  
}
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
    serviceBusClient.Run();

    while (!cancellationToken.IsCancellationRequested)
    {
        // empty loop to keep running for lifetime of pod       
    }
}
如果删除
async
,我显然需要返回一些东西。我尝试了
Task.CompletedTask
,但这需要我将返回类型更改为
Task

如果我有
async
,我需要
等待一些东西,但我不确定是什么

这感觉不对。我假设我需要更改
ServiceBusClient
中的某些内容,但我不确定是什么,因为
ProcessMessagesAsync
是异步的,并且按照我的理解在后台执行繁重的工作


我只想让我的网络应用开始监听消息,直到它死掉。我该怎么做呢?

我放弃了使用
BackgroundService
,转而实现了
IHostedService

    public class MessageListenerService : IHostedService
    {
        private readonly IServiceBusClient client;
        private readonly ITelemetryClient applicationInsights;

        public MessageListenerService(IServiceProvider serviceProvider)
        {
            client = serviceProvider.GetService<IServiceBusClient>();
            applicationInsights = serviceProvider.GetService<ITelemetryClient>();
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            applicationInsights.TrackTrace(new TraceTelemetry("MessageListenerService is starting"));

            client.Run();

            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            applicationInsights.TrackTrace(new TraceTelemetry("MessageListenerService is stopping"));
            return client.Stop();
        }
    }
公共类MessageListenerService:IHostedService
{
专用只读服务器ViceBusclient客户端;
私有只读ITelemetryClient应用程序权限;
公共消息ListenerService(IServiceProvider服务提供商)
{
client=serviceProvider.GetService();
applicationInsights=serviceProvider.GetService();
}
公共任务StartSync(CancellationToken CancellationToken)
{
TrackTrace(新的TraceTelemetry(“MessageListenerService正在启动”);
client.Run();
返回Task.CompletedTask;
}
公共任务StopAsync(CancellationToken CancellationToken)
{
TrackTrace(新的TraceTelemetry(“MessageListenerService正在停止”);
返回client.Stop();
}
}
如果您发现此代码存在问题,请在评论中告诉我,我会根据需要进行更新


最后,我们还是为它创建了一个控制台应用程序。

您使用的是什么版本的.Net Core?我运行了一个类似的场景(通过IHostedService的服务总线侦听器),并使用了任务返回类型=>return Task.CompletedTask;在.NETCore2.1上没有问题。与演示一样,代码并不是特别优雅,但如果有帮助的话,就在这里:我在start方法中忽略了取消标记,但这对这个问题不重要。最后我实现了一个
IHostedService
,可以从
Start
方法启动客户端。但是,无论如何,我们必须重构到控制台应用程序,所以现在就完成了:P.使用控制台应用程序还可以更容易地创建更可测试的ServiceBusClient和消息处理程序。