正确使用ParallelOptions、TaskCreationOptions和Task.Factory.StartNew的方法是什么?

4

请建议哪种方法(如果有的话)适合正确且高效地使用ParallelOptions、TaskCreationOptions和Task.Factory.StartNew(() =>。

private void NeedToUse_MaxDegreeOfParallelism_Method1()
{
    CancellationTokenSource tokenFor_task = new CancellationTokenSource();

    ParallelOptions parOpts = new ParallelOptions();
    //parOpts.CancellationToken = tokenFor_task_tpl_Pair01.Token;
    parOpts.MaxDegreeOfParallelism = Environment.ProcessorCount;
    //parOpts.TaskScheduler = TaskScheduler.Default;

    TaskCreationOptions tco = new TaskCreationOptions();
    tco = TaskCreationOptions.PreferFairness;

    Task task = null;
    task = Task.Factory.StartNew(() =>
    {
        while (!tokenFor_task.IsCancellationRequested)
        {
            LongRunningMethod();
        }
    }, tokenFor_task.Token, tco, TaskScheduler.Default);
}


private void NeedToUse_MaxDegreeOfParallelism_Method2()
{
    //CancellationTokenSource tokenFor_task = new CancellationTokenSource();

    ParallelOptions parOpts = new ParallelOptions();
    parOpts.CancellationToken = tokenFor_task_tpl_Pair01.Token;
    parOpts.MaxDegreeOfParallelism = Environment.ProcessorCount;
    parOpts.TaskScheduler = TaskScheduler.Default;

    TaskCreationOptions tco = new TaskCreationOptions();
    tco = TaskCreationOptions.PreferFairness;

    Task task = null;
    task = Task.Factory.StartNew(() =>
    {
        while (!parOpts.CancellationToken.IsCancellationRequested)
        {
            LongRunningMethod();
        }
    }, parOpts.CancellationToken, tco, parOpts.TaskScheduler);
}

private void NeedToUse_MaxDegreeOfParallelism_Method3()
{
    CancellationTokenSource tokenFor_task = new CancellationTokenSource();

    ParallelOptions parOpts = new ParallelOptions();
    //parOpts.CancellationToken = tokenFor_task_tpl_Pair01.Token;
    parOpts.MaxDegreeOfParallelism = Environment.ProcessorCount;
    //parOpts.TaskScheduler = TaskScheduler.Default;

    TaskCreationOptions tco = new TaskCreationOptions();
    tco = TaskCreationOptions.PreferFairness;

    Task task = null;
    task = Task.Factory.StartNew(() =>
    {
         Parallel.Invoke(parOpts, () =>
        //while is already in LongRunningMethod() because can not be here
        //while (!tokenFor_task.IsCancellationRequested) 
        //{
            LongRunningMethod()
        //}
        );
    }, tokenFor_task.Token, tco, TaskScheduler.Default);
}

private void NeedToUse_MaxDegreeOfParallelism_Method4()
{
    CancellationTokenSource tokenFor_task = new CancellationTokenSource();

    ParallelOptions parOpts = new ParallelOptions();
    //parOpts.CancellationToken = tokenFor_task_tpl_Pair01.Token;
    parOpts.MaxDegreeOfParallelism = Environment.ProcessorCount;
    //parOpts.TaskScheduler = TaskScheduler.Default;

    TaskCreationOptions tco = new TaskCreationOptions();
    tco = TaskCreationOptions.PreferFairness;

    Task task = null;
    Parallel.Invoke(parOpts, () =>
        task = Task.Factory.StartNew(() =>
        {
            while (!tokenFor_task.IsCancellationRequested)
            {
                LongRunningMethod();
            }
        }, tokenFor_task.Token, tco, TaskScheduler.Default)
    );
}

目前我没有遇到任何错误。第一种和第二种方法都没有考虑到我需要使用的MaxDegreeOfParallelism。理想情况下,我不想使用Parallel.Invoke,但如何在Task.Factory.StartNew中包含parOpts.MaxDegreeOfParallelism呢?

1个回答

6
您的代码和问题不是很明确。因为Task.Factory.StartNew()执行的是单个操作,所以它不接受MaxDegreeOfParallelism参数。虽然Parallel.Invoke()接受该参数,但是在只有一个操作时使用该方法没有意义。
我认为您应该退后一步,看看您实际想要实现什么,然后可能会问一个新问题。
编辑:现在我终于理解您想要做什么了:在每个核心上,您想要执行一个单独的循环。为了做到这一点,您可以例如使用Parallel.For()
Parallel.For(0, Environment.ProcessorCount, parOpts, () =>
    {
        while (!tokenFor_task.IsCancellationRequested)
        {
            LongRunningMethod();
        }
    });

我希望在可能的情况下,LongRunningMethod()能够并行地在所有核心上执行。 - as74

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接