首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET排队的任务(带有异步/等待)

.NET排队的任务(带有异步/等待)
EN

Stack Overflow用户
提问于 2016-12-06 21:20:37
回答 1查看 138关注 0票数 5

我有大量需要执行的任务(~1000)。我在一个4核处理器上运行,所以我想一次并行地处理4个任务。

为了给您一个起点,下面是一些示例代码。

代码语言:javascript
复制
class Program
{
    public class LongOperation
    {
        private static readonly Random RandomNumberGenerator = new Random(0);
        const int UpdateFrequencyMilliseconds = 100;

        public int CurrentProgress { get; set; }

        public int TargetProcess { get; set; }

        public LongOperation()
        {
            TargetProcess = RandomNumberGenerator.Next(
                (int)TimeSpan.FromSeconds(5).TotalMilliseconds / UpdateFrequencyMilliseconds, 
                (int)TimeSpan.FromSeconds(10).TotalMilliseconds / UpdateFrequencyMilliseconds);
        }

        public async Task Execute()
        {
            while (!IsCompleted)
            {
                await Task.Delay(UpdateFrequencyMilliseconds);
                CurrentProgress++;
            }
        }

        public bool IsCompleted => CurrentProgress >= TargetProcess;
    }

    static void Main(string[] args)
    {
        Task.Factory.StartNew(async () =>
        {
            var operations = new List<LongOperation>();

            for(var x = 1; x <= 10; x++)
                operations.Add(new LongOperation());

            await ProcessOperations(4, operations);
        }).Wait();
    }

    public static async Task ProcessOperations(int maxSimultaneous, List<LongOperation> operations)
    {
        await Task.WhenAll(operations.Select(x => x.Execute()));
        // TODO: Process up to 4 operations at a time, until every operation is completed.
    }
}

我想要一些输入,说明我将使用哪些类,以及如何构造ProcessOperations,一次最多处理4个操作,直到所有操作都在一个可等待的Task中完成为止。

我正在考虑以某种方式使用SemaphoreSlim对象,因为它似乎是为了控制资源/进程。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-11 23:59:23

如前所述,您需要使用带有两个块的方便的TPL数据流库来在处理之前存储消息,并对它们进行实际操作:

代码语言:javascript
复制
// storage
var operations = new BufferBlock<LongOperation>();
// no more than 4 actions at the time
var actions = new ActionBlock<LongOperation>(x => x.Execute(),
    new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 4 });

// consume new operations automatically
operations.LinkTo(actions);
for(var x = 1; x <= 10; ++x)
{
    // blocking sending
    operations.Post(new LongOperation());
    // awaitable send for async operations
    // await operations.SendAsync(new LongOperation());
}

此外,您还可以通过设置缓冲区的BoundedCapacity选项来增加一些限制,比如当时不超过30个操作。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41005135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档