gpt4 book ai didi

.net - 如何将参数传递给排队的后台任务(.net 核心)

转载 作者:行者123 更新时间:2023-12-04 07:50:12 29 4
gpt4 key购买 nike

在我的网络应用程序中,我对长时间运行的任务进行了操作,我想在后台调用此任务。因此,根据文档 .net core 3.1 Queued background tasks我为此使用这样的代码:

public interface IBackgroundTaskQueue
{
ValueTask QueueBackgroundWorkItemAsync(Func<CancellationToken, ValueTask> workItem);

ValueTask<Func<CancellationToken, ValueTask>> DequeueAsync(CancellationToken cancellationToken);
}

public class BackgroundTaskQueue : IBackgroundTaskQueue
{
private readonly Channel<Func<CancellationToken, ValueTask>> _queue;

public BackgroundTaskQueue(int capacity)
{
var options = new BoundedChannelOptions(capacity){FullMode = BoundedChannelFullMode.Wait};
_queue = Channel.CreateBounded<Func<CancellationToken, ValueTask>>(options);
}

public async ValueTask QueueBackgroundWorkItemAsync(Func<CancellationToken, ValueTask> workItem)
{
if (workItem == null)throw new ArgumentNullException(nameof(workItem));
await _queue.Writer.WriteAsync(workItem);
}

public async ValueTask<Func<CancellationToken, ValueTask>> DequeueAsync(CancellationToken cancellationToken)
{
var workItem = await _queue.Reader.ReadAsync(cancellationToken);
return workItem;
}
}
和托管服务
public class QueuedHostedService : BackgroundService
{
private readonly ILogger<QueuedHostedService> _logger;

public QueuedHostedService(IBackgroundTaskQueue taskQueue, ILogger<QueuedHostedService> logger)
{
TaskQueue = taskQueue;
_logger = logger;
}

public IBackgroundTaskQueue TaskQueue { get; }

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await BackgroundProcessing(stoppingToken);
}

private async Task BackgroundProcessing(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var workItem = await TaskQueue.DequeueAsync(stoppingToken);

try
{
await workItem(stoppingToken);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error occurred executing {WorkItem}.", nameof(workItem));
}
}
}

public override async Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Queued Hosted Service is stopping.");
await base.StopAsync(stoppingToken);
}
}
然后我注册所有服务
services.AddHostedService<QueuedHostedService>();
services.AddSingleton<IBackgroundTaskQueue>(new BackgroundTaskQueue(queueCapacity));
然后我可以通过像这样的示例调用不带参数来成功使用它
public async Task<TenantBo> RegisterCompanyAsync(AddTenantBo addTenantBo)
{
var tenantBo = new TenantBo();

try
{
_companyRegistrationLogHelper.SetInfoLog(GetTenantId(tenantBo),
"Start create company: " + JsonConvert.SerializeObject(addTenantBo));

InitOnCreateCompanyTasks(tenantBo);

//skip if already create tenant
tenantBo = await CreateTenantAsync(tenantBo, addTenantBo);

//run in background
_companyRegistationQueue.QueueBackgroundWorkItemAsync(RunRegistrationCompanyMainAsync);

return tenantBo;
}
catch (Exception e)
{
//some logs
return tenantBo;
}
}

private async ValueTask RunRegistrationCompanyMainAsync(CancellationToken cancellationToken)
{
//some await Tasks
}

private async ValueTask RunRegistrationCompanyMainAsync(string tenantId, CancellationToken cancellationToken)
{
//some await Tasks
}
所以我只能用一个参数调用 RunRegistrationCompanyMainAsync(CancellationToken cancelToken) 而不能用两个参数调用 RunRegistrationCompanyMainAsync(string tenantId, CancellationToken cancelToken)
你能帮我传递字符串参数作为这个任务的参数吗?

最佳答案

QueueBackgroundWorkItemAsync(RunRegistrationCompanyMainAsync)调用编译器实际执行cast from method group into a delegate .但是要提供 Func 的实例委托(delegate)您不限于方法组,您可以提供 lambda expression例如:

 var someTenantId = ....
.....
_companyRegistationQueue.QueueBackgroundWorkItemAsync(ct => RunRegistrationCompanyMainAsync(someTenantId, ct));

关于.net - 如何将参数传递给排队的后台任务(.net 核心),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67026971/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com