gpt4 book ai didi

c# - ASP .Net Core Queued 后台任务并行处理

转载 作者:行者123 更新时间:2023-12-04 12:34:30 25 4
gpt4 key购买 nike

我有一个 ASP .NET 核心 Web API,它使用描述的排队后台任务
here .
我使用了提供的代码示例并添加了 IBackgroundTaskQueue , BackgroundTaskQueueQueuedHostedService完全按照文章中的描述。
在我的 Startup.cs , 我只注册一个 QueuedHostedService实例如下:services.AddHostedService<QueuedHostedService>();来自WebApi Controller 的任务通过QueuedHostedService 入队然后出队并一一执行。 .
我希望允许多个后台处理线程出列并执行传入的任务。
我能想到的最直接的解决方案是注册一个以上 QueuedHostedService 的实例。在我的 Startup.cs .即,像这样:

 int maxNumOfParallelOperations;
var isValid = int.TryParse(Configuration["App:MaxNumOfParallelOperations"], out maxNumOfParallelOperations);

maxNumOfParallelOperations = isValid && maxNumOfParallelOperations > 0 ? maxNumOfParallelOperations : 2;

for (int index = 0; index < maxNumOfParallelOperations; index++)
{
services.AddHostedService<QueuedHostedService>();
}
我还注意到,多亏了 BackgroundTaskQueue 中的单个信号量, QueuedHostedService实例并不是一直都在工作,而是只有在队列中有新任务可用时才会唤醒。
这个解决方案在我的测试中似乎工作得很好。
但是,在这个特定的用例中 - 它真的是一个有效的、推荐的并行处理解决方案吗?

最佳答案

您可以使用 IHostedService用多个线程来消耗IBackgroundTaskQueue .
这是一个基本的实现。我假设您使用的是相同的 IBackgroundTaskQueueBackgroundTaskQueue描述 here .

public class QueuedHostedService : IHostedService
{
private readonly ILogger _logger;

private readonly Task[] _executors;
private readonly int _executorsCount = 2; //--default value: 2
private CancellationTokenSource _tokenSource;
public IBackgroundTaskQueue TaskQueue { get; }

public QueuedHostedService(IBackgroundTaskQueue taskQueue,
ILoggerFactory loggerFactory,
IConfiguration configuration)
{
TaskQueue = taskQueue;
_logger = loggerFactory.CreateLogger<QueuedHostedService>();

if (ushort.TryParse(configuration["App:MaxNumOfParallelOperations"], out var ct))
{
_executorsCount = ct;
}
_executors = new Task[_executorsCount];
}

public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Queued Hosted Service is starting.");

_tokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

for (var i = 0; i < _executorsCount; i++)
{
var executorTask = new Task(
async () =>
{
while (!cancellationToken.IsCancellationRequested)
{
#if DEBUG
_logger.LogInformation("Waiting background task...");
#endif
var workItem = await TaskQueue.DequeueAsync(cancellationToken);

try
{
#if DEBUG
_logger.LogInformation("Got background task, executing...");
#endif
await workItem(cancellationToken);
}
catch (Exception ex)
{
_logger.LogError(ex,
"Error occurred executing {WorkItem}.", nameof(workItem)
);
}
}
}, _tokenSource.Token);

_executors[i] = executorTask;
executorTask.Start();
}

return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Queued Hosted Service is stopping.");
_tokenSource.Cancel(); // send the cancellation signal

if (_executors != null)
{
// wait for _executors completion
Task.WaitAll(_executors, cancellationToken);
}

return Task.CompletedTask;
}
}
您需要在 ConfigureServices注册服务在 Startup类(class)。
...
services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
services.AddHostedService<QueuedHostedService>();
...
另外,您可以在配置中设置线程数( appsettings.json )
...
"App": {
"MaxNumOfParallelOperations": 4
}
...

关于c# - ASP .Net Core Queued 后台任务并行处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62867167/

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