使用SemaphoreSlim并行运行.NET任务有时不运行?

问题描述 投票:0回答:0

我正在设置单独的 .NET (C#) 任务以并行运行,并希望将可以同时运行的任务数量限制为 10 个。我看到的大多数实现此目的的示例都使用了

SemaphoreSlim
并且我有将我的逻辑设置为与大多数示例相同:

            // Limit the concurrent number of threads to 10
            var throttler = new SemaphoreSlim(10);

            // Create a list of tasks to run
            var tasks = images.Select(async image =>
            {
                _logger.Info("WAITING FOR THROTTLER");
                await throttler.WaitAsync();
                try
                {
                    _logger.Info("ABOUT TO DOWNLOAD IMAGE FROM API A");
                    var imageData = await DownloadImage(...);

                    if (imageData != null)
                    {
                        _logger.Info("ABOUT TO UPLOAD IMAGE TO API B");
                        await AddFileAsync(...);
                    }
                }
                catch (Exception e)
                {
                    _logger.Error("Failed on UploadImages: " + e.Message);
                }
                finally
                {
                    throttler.Release();// Always release the semaphore when done
                }
            });

            await Task.WhenAll(tasks);// Now we actually run the tasks

对于上下文,每个任务从 API (A) 下载图像数据,然后通过

HttpClient
将该数据上传到不同的 API (B)。

用 12 张图片测试,有时效果很好。但是,存在一个间歇性问题,有时 2 张图像无法通过,API 调用不会抛出或返回任何错误。我将日志放入以缩小范围,发现在前 10 个进程之后,最后 2 个进程从未通过“WAITING FOR THROTTLER”,所以它似乎一直在等待信号量释放?我想知道为什么会发生这种情况,尤其是当它有时起作用时,似乎是某种时间问题?感谢是否有人可以阐明这里发生的事情。

*我还会注意到,使用

Parallel.ForEachAsync
不是一个选项,因为这个项目在 .NET 4.6.2 上运行,现在升级不是一个选项。

c# concurrency task semaphore .net-4.6.2
© www.soinside.com 2019 - 2024. All rights reserved.