gpt4 book ai didi

c# - 多个工作线程与一个使用异步/等待的工作线程

转载 作者:行者123 更新时间:2023-11-30 14:31:53 25 4
gpt4 key购买 nike

我的代码目前有以下 10 个工作线程。每个工作线程继续从队列中轮询作业,然后处理长时间运行的作业。

for (int k=0; k<10; k++)
{
Task.Factory.StartNew(() => DoPollingThenWork(), TaskCreationOptions.LongRunning);
}

void DoPollingThenWork()
{
while (true)
{
var msg = Poll();
if (msg != null)
{
Thread.Sleep(3000); // process the I/O bound job
}
}
}

我正在重构底层代码以使用异步/等待模式。我想我可以将上面的代码重写为以下代码。它使用一个主线程不断创建异步任务,并使用 SemaphoreSlim 将并发任务数限制为 10。

Task.Factory.StartNew(() => WorkerMainAsync(), TaskCreationOptions.LongRunning);

async Task WorkerMainAsync()
{
SemaphoreSlim ss = new SemaphoreSlim(10);
while (true)
{
await ss.WaitAsync();
Task.Run(async () =>
{
await DoPollingThenWorkAsync();
ss.Release();
});
}
}

async Task DoPollingThenWorkAsync()
{
var msg = Poll();
if (msg != null)
{
await Task.Delay(3000); // process the I/O-bound job
}
}

两者的行为应该相同。但我认为第二个选项似乎更好,因为它不会阻塞线程。但缺点是我不能等待(优雅地停止任务),因为任务就像火了,忘记了。第二种选择是替代传统工作线程模式的正确方法吗?

最佳答案

当您拥有异步代码时,您通常没有理由使用 Task.Run()(或者,更糟糕的是,Task.Factory.StartNew()) .这意味着您可以将代码更改为如下所示:

await WorkerMainAsync();

async Task WorkerMainAsync()
{
SemaphoreSlim ss = new SemaphoreSlim(10);
while (true)
{
await ss.WaitAsync();
// you should probably store this task somewhere and then await it
var task = DoPollingThenWorkAsync();
}
}

async Task DoPollingThenWorkAsync(SemaphoreSlim semaphore)
{
var msg = Poll();
if (msg != null)
{
await Task.Delay(3000); // process the I/O-bound job
}

// this assumes you don't have to worry about exceptions
// otherwise consider try-finally
semaphore.Release();
}

关于c# - 多个工作线程与一个使用异步/等待的工作线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19341727/

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