开发者

Threading in C# with limited number of jobs and limited number of active threads

开发者 https://www.devze.com 2023-03-30 21:54 出处:网络
I have a loop that looks something like this: var list = new List<float>(); while (list.Count开发者_如何学运维 < wantedNumberOfJobs)

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

0

精彩评论

暂无评论...
验证码 换一张
取 消