Ask a questionAsk a question
 

Answercannot set TaskManager.Current.Policy?

  • Monday, June 09, 2008 7:37 AMGeorge112 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I could do this in the previous CTP:
        TaskManager.Current.Policy = new TaskManagerPolicy(2, 2, 2, 0, true); // I just want to set the number of threads generally

    however, in the June CTP:
        TaskManager.Current.Policy = new TaskManagerPolicy(2, 2, 2, 0, ThreadPriority.Normal);
    results:
        'System.Threading.Tasks.TaskManager.Policy' cannot be assigned to -- it is read only   

    yes, it is read only, is I see:
    class TaskManager {
    public static TaskManager Current { get; }
    public TaskManagerPolicy Policy { get; }
    }

    The Policy is also read-only, so I cannot set that either.
    Is it possible to set the Current TaskManagerPolicy somehow?
    so, I don't have to use the more cumbersome TaskManager parameter version of the ForEach:

    public static void ForEach<TSource, TLocal>(IEnumerable<TSource> source, Func<TLocal> threadLocalInit, Action<TSource, int, ParallelState<TLocal>> body, Action<TLocal> threadLocalFinally, TaskManager manager, TaskCreationOptions options);

    instead of the simple

    public static void ForEach<TSource>(IEnumerable<TSource> source, Action<TSource> body);

Answers

  • Tuesday, June 10, 2008 5:16 AMStephen Toub - MSFTMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Yes, we've been redesigning TaskManager's APIs based on feedback, both from customer's and from reviews for reliability and the like.  There were several issues with the old design.  For example, modifying the policy of an existing TaskManager can have negative implications on algorithms concurrently using the TaskManager, especially when you consider that the same TaskManager instance can be passed around, with various pieces of code making decisions based on a particular instance's policy.  To avoid such issues (which can be quite nasty), we've opted for a design where the default policy cannot be changed programmatically.  However, we do plan to support configuration-based modification of the default policy.  Additionally, the semantics of TaskManager.Current are such that you don't have to use the complicated overloads of ForEach if you don't want to; you can simple update the Current TaskManager by using another task.  For example:

     

    Task.Create(delegate

    {

        Parallel.ForEach(...,

        {

            ... // body

        });

    }, newTm).Wait();

     

    That said, I'd be very interested in understanding scenarios where it's important for you to be able to change the policy for the current TaskManager.  Any and all feedback is very welcome!

All Replies

  • Tuesday, June 10, 2008 5:16 AMStephen Toub - MSFTMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Yes, we've been redesigning TaskManager's APIs based on feedback, both from customer's and from reviews for reliability and the like.  There were several issues with the old design.  For example, modifying the policy of an existing TaskManager can have negative implications on algorithms concurrently using the TaskManager, especially when you consider that the same TaskManager instance can be passed around, with various pieces of code making decisions based on a particular instance's policy.  To avoid such issues (which can be quite nasty), we've opted for a design where the default policy cannot be changed programmatically.  However, we do plan to support configuration-based modification of the default policy.  Additionally, the semantics of TaskManager.Current are such that you don't have to use the complicated overloads of ForEach if you don't want to; you can simple update the Current TaskManager by using another task.  For example:

     

    Task.Create(delegate

    {

        Parallel.ForEach(...,

        {

            ... // body

        });

    }, newTm).Wait();

     

    That said, I'd be very interested in understanding scenarios where it's important for you to be able to change the policy for the current TaskManager.  Any and all feedback is very welcome!

  • Tuesday, June 10, 2008 7:59 AMGeorge112 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Dear Stephen,

    Ok, I understand the reasons. Probably it was a wise move.
    However, I would vote for another form of
    ForEach, the simple one, that contains
    TaskManager and TaskCreationOptions as parameters.
    public static void ForEach<TSource>(IEnumerable<TSource> source, Action<TSource> body, TaskManager manager, TaskCreationOptions options);

     

    >I'd be very interested in understanding scenarios where it's important for you to be able to change the policy for >the current TaskManager.  Any and all feedback is very welcome!

    My application is not CPU bound, but bandwidth bound (or it can be file IO bound).
    So, for example, I have a crawler that spawns "explicitely" 12 threads to crawl homepages.
    By default, Taskmanager creates 2 threads on my dual core, however, I would like
    to have 12 executions on single core, dual core, quad core, etc.
    I figured out that I have to use another TaskManager, not the default one.
    My code is
    ForEch (var i in collection of 6000homepages)  // hopefully parallel
    {
     CrawlHomepageAndProcess(i);  
    }

    I would like to spawn  for example  12 executionssimultaneously.
    Maybe you can come up with another design.

    btw, Thank you so much for answering,
    and your code sample suggestion completely fullfills my desire.
    Smile