Note that there are some explanatory texts on larger screens.

plurals
  1. POCreating private object instances for use within System.Threading.Tasks.Task?
    primarykey
    data
    text
    <p>Let's say I have a business object that is very expensive to instantiate, and I would never want to create more than say 10 instances of that object in my application. So, that would mean I would never want to have more than 10 concurrent worker threads running at one time.</p> <p>I'd like to use the new System.Threading.Tasks to create a task like this:</p> <pre><code> var task = Task.Factory.StartNew(() =&gt; myPrivateObject.DoSomethingProductive()); </code></pre> <p>Is there a sample out there that would show how to:</p> <ol> <li>create an 'object pool' for use by the TaskFactory? </li> <li>limit the TaskFactory to a specified number of threads?</li> <li>lock an instance in the object pool so it can only be used by one task at a time?</li> </ol> <hr> <p>Igby's answer led me to this <a href="http://www.codethinked.com/blockingcollection-and-iproducerconsumercollection" rel="nofollow">excellent blog post</a> from Justin Etheridge. which then prompted me to write this sample:</p> <pre><code>using System; using System.Collections.Concurrent; using System.Threading.Tasks; namespace MyThreadedApplication { class Program { static void Main(string[] args) { // build a list of 10 expensive working object instances var expensiveStuff = new BlockingCollection&lt;ExpensiveWorkObject&gt;(); for (int i = 65; i &lt; 75; i++) { expensiveStuff.Add(new ExpensiveWorkObject(Convert.ToChar(i))); } Console.WriteLine("{0} expensive objects created", expensiveStuff.Count); // build a list of work to be performed Random r = new Random(); var work = new ConcurrentQueue&lt;int&gt;(); for (int i = 0; i &lt; 1000; i++) { work.Enqueue(r.Next(10000)); } Console.WriteLine("{0} items in work queue", work.Count); // process the list of work items in fifteen threads for (int i = 1; i &lt; 15; i++) { Task.Factory.StartNew(() =&gt; { while (true) { var expensiveThing = expensiveStuff.Take(); try { int workValue; if (work.TryDequeue(out workValue)) { expensiveThing.DoWork(workValue); } } finally { expensiveStuff.Add(expensiveThing); } } }); } } } } class ExpensiveWorkObject { char identity; public void DoWork(int someDelay) { System.Threading.Thread.Sleep(someDelay); Console.WriteLine("{0}: {1}", identity, someDelay); } public ExpensiveWorkObject(char Identifier) { identity = Identifier; } } </code></pre> <p>So, I'm using the BlockingCollection as an object pool, and the worker threads don't check the queue for available work until they have an exclusive control over one of the expensive object instances. I <em>think</em> this meets my requirements, but I would really like feedback from people who know this stuff better than I do...</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload