cannot set TaskManager.Current.Policy?
- 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
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
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!
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.


