任务MaxDegreeOfParallelism是否可以每次从列表中的前n个对象获取? [英] Can Task MaxDegreeOfParallelism can take every time the first n object from my list?

查看:52
本文介绍了任务MaxDegreeOfParallelism是否可以每次从列表中的前n个对象获取?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在我的函数中打开n个并发线程:

I am opening n concurrent threads in my function:

List<string> _files = new List<string>();

public void Start()
{
    CancellationTokenSource _tokenSource = new CancellationTokenSource();
    var token = _tokenSource.Token;

    Task.Factory.StartNew(() =>
    {
        try
        {
            Parallel.ForEach(_files,
                new ParallelOptions
                {
                    MaxDegreeOfParallelism = 5 //limit number of parallel threads 
                },
                file =>
                {
                    if (token.IsCancellationRequested)
                        return;
                    //do work...
                });
        }
        catch (Exception)
        { }

    }, _tokenSource.Token).ContinueWith(
        t =>
        {
            //finish...
        }
    , TaskScheduler.FromCurrentSynchronizationContext() //to ContinueWith (update UI) from UI thread
    );
        }

打开线程后,我注意到它从列表中选择了随机文件. 每次都可以从列表中选择第一个n元素吗?

After the threads opened i have noticed that it chooses random files from my list. is it possible to choose every time the first n element from my list ?

推荐答案

要获得所需的行为,您需要编写

To get the behavior you want you need to write a custom partitioner, The reason it looks "random" is right now it is batching out the file list in blocks so if your source list was

List<string> files = List<string> { "a", "b", "c", "d", "e", "f", "g", "h", "i" };

在对其进行分区时,它可能会像这样平均分配(如果Max为3个线程):

when it partitions it it may split it evenly like so (if Max was 3 threads):

  • 线程1的工作清单:"a","b","c"
  • Thread2的工作清单:"d","e","f"
  • Thread3的工作清单:"g","h","i"

因此,如果您看到正在处理的文件,则可能看起来像

So if you watched the files being processed it may look like

"a", "d", "g", "e", "b", "h", "c", "f", "i"

如果您创建一个自定义分区程序,则可以一次使用一项而不是一批,以使工作列表看起来像

If you make a custom partitioner you can have it take one item at a time instead of a batch at a time to make the work list look like

  • Thread1的工作清单:"a",GetTheNextUnprocessedString()
  • Thread2的工作清单:"b",GetTheNextUnprocessedString()
  • Thread3的工作清单:"c",GetTheNextUnprocessedString()
  • Thread1's work list: "a", GetTheNextUnprocessedString()
  • Thread2's work list: "b", GetTheNextUnprocessedString()
  • Thread3's work list: "c", GetTheNextUnprocessedString()

如果您使用的是.NET 4.5,则可以使用

If you are using .NET 4.5 you can use this factory like so:

Parallel.ForEach(Partitioner.Create(_files, EnumerablePartitionerOptions.NoBuffering),
                new ParallelOptions
                {
                    MaxDegreeOfParallelism = 5 //limit number of parallel threads 
                },
                (file, loopstate, index) =>
                {
                    if (token.IsCancellationRequested)
                        return;
                    //do work...
                });

如果您不使用.NET 4.5,那么这并不是一件容易的事,因此我不会在这里为您编写.阅读我在顶部链接的MSDN文章,您最终可以弄清楚.

If you are not using .NET 4.5, it is not a trivial task so I am not going to write it here for you. Read the MSDN article I linked at the top and you will be able to figure it out eventually.

我要做的是问自己我真的需要按顺序处理文件吗?"如果您不需要它们来进行排序,那么通过强制执行订单,您可能要做的唯一一件事就是可能会减慢流程速度.

What I would do is ask yourself "do I really need the files to be processed in order?" if you don't need them to be in order let it do its own ordering as the only thing you will likely do by enforcing a order is potentially slowing down the process.

这篇关于任务MaxDegreeOfParallelism是否可以每次从列表中的前n个对象获取?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆