来自 Quartz 作业死锁的 Masstransit IRequestClient.Request 调用

Masstransit IRequestClient.Request call from the Quartz job deadlock

我有一个通过 Masstransit IRequestClient.Request 方法调用来调用业务服务的报告。

如果此报告是从 UI(ASP.NET MVC 控制器)构建的,一切正常,但如果同一个报告是从 Quartz .net 作业方法调用构建的,则永远不会 returns .

这是代码示例:

//client is an instance of MessageRequestClient class
var response = await client.Request(new GetEntityCommand
        {
            Ids = ids,
            ExcludeDeleted = excludeDeleted
        }).ConfigureAwait(false);

消费者代码:

public class GetEntityCommandConsumer : IConsumer<IGetEntityCommand>
{
    private readonly IEntityService _entityService;

    public GetEntityCommandConsumer(IEntityService entityService)
    {
        _entityService= entityService;
    }

    public Task Consume(ConsumeContext<IGetEntityCommand> context)
    {
        var ids = context.Message.Ids;
        var entities = _entityService.GetAll(ids, context.Message.ExcludeDeleted); //database NHibernate call
        var result =
            context.RespondAsync(new GetEntityCommandResponse
            {
                Success = true,
                Entities = entities.Select(x => x.ToDTO).ToList()
            });

        return result;
    }
}

看起来消费者调用没有被等待,范围在它完成之前就被释放了,所以你遇到了死锁。

试试这个:

public async Task Consume(ConsumeContext<IGetEntityCommand> context)
{
    var ids = context.Message.Ids;
    var entities = _entityService.GetAll(ids, context.Message.ExcludeDeleted); //database NHibernate call
    await
        context.RespondAsync(new GetEntityCommandResponse
        {
            Success = true,
            Entities = entities.Select(x => x.ToDTO).ToList()
        });
}

像往常一样,问题出在我自己的代码中 :) 有两个 IBusControl 实例,但预期只有一个。作业中使用的 IBusControl 未启动。通过使用 "true" 单例 IBusControl 修复。