I have a loop that looks something like this:
var list = new List<float>();
while (list.Count开发者_如何学运维 < wantedNumberOfJobs)
{
var resource = ... //gets the resource
lock (resource)
{
ThreadPool.QueueUserWorkItem(DoWork, /*wrap resource and list into an object*/);
}
}
//continue pass this point when all the threads are finished
And the work method:
private void DoWork(object state)
{
var list = (/*wrapperObject*/)state.List;
var someFloat = //do the work to get the number
lock (list)
{
list.Add(someFloat);
}
}
Essentially I want to do a large, but a specific (given by wantedNumberOfJobs
) number of jobs done. Each of these jobs inserts a single item into the list
as you can see in the DoWork
method.
I am not certain that this code is assuring me that list
will contain wantedNumberOfJobs
items past the designated point. I'd also like to limit the number of active threads. I've used the System.Threading.Semaphore
class, but am not sure this is the best solution.
I'd appreciate any help. Thanks!
Perhaps you can use Parallel.For, like so:
Parallel.For(0, wantedNumberOfJobs, i => {
var resource = ... //gets the resource
DoWork(Resource);
});
You should really get a copy of Patterns for Parallel Programming: Understanding and Applying Parallel Patterns with the .NET Framework 4.
It explains who to use the parallel extensions in .net 4 and how you can influence how many jobs are running concurrently. For your list you should also take a look into the Concurrent namespace to find a thread-safe alternative.
Since you tagged this C#4, consider using Tasks from the TaskPool rather than Threads from the TreadPool. This will limit the number of threads you use based on the number of processors you have. Also, consider removing some of the locks as each of them require context switching and process locking which effectively limit or even eliminate the advantage of using multiple threads in the first place.
You'll likely end up with many more than wantedNumberOfJobs
items in list
. This is because the while loop is deciding whether or not to queue a new work item based on the current contents of list. Depending on how long DoWork
takes, it could queue hundreds or thousands of items before any are added to list
.
One way to work around this problem is to have the while loop keep track of the number of work items it queues up, and to stop when it gets to wantedNumberOfJobs
.
PLINQ may be sufficient for you? http://msdn.microsoft.com/en-us/library/dd460714.aspx
精彩评论