title: Equivalent of Parallel.For's localInit and localFinally to use in TPL Dataflow blocks when MaxDegreeOfParallelism > 1
body: <p>I have a <code>TransformBlock&lt;int, int&gt;</code> that has <code>MaxDegreeOfParallelism = 6</code>. I have also identified that the <code>Func&lt;int, int&gt;</code> that is passed to the block's constructor (to be executed for each posted item) could be logically broken down into an expensive initialization routine and a body that mutates the function's local variables. It would be more efficient if I could refactor the function into a class named <code>TransformBlockState</code>, perform the initialization once per concurrent action (just like <code>Parallel.For</code>'s <code>localInit</code> callback) and then allow TPL Dataflow to ensure that the state is never mutated by more than one item at a time.</p>
  
  <p><strong>Before refactoring:</strong></p>
  
  <pre><code>Func&lt;int, int&gt; original = x => {
      // method local variables
      // expensive initialization routine to setup locals
      // perform action on local variables
      // potentially expensive teardown
  }</code></pre>
  
  <p><strong>After refactoring:</strong></p>
  
  <pre><code>public sealed class TransformBlockState&lt;TIn, TOut&gt; : IDisposable
  {
      // instance state
  
      public TransformBlockState()
      {
          // expensive initialization routine
      }
  
      public TOut Transform(TIn value)
      {
          // called many times but never concurrently for the same instance
      }
  
      public void Dispose()
      {
          // tear down state
      }
  }</code></pre>
  
  <p>Does something akin to the <code>localInit</code> (for <code>.ctor</code>) and <code>localFinally</code> (for <code>Dispose</code>) callbacks already exist in the TPL Dataflow library?</p>
  
  <p>I want to avoid having a <code>ConcurrentStack&lt;TransformBlockState&gt;</code> (lots of unnecessary locking) and I want to avoid storing the <code>TransformBlockState</code> in a <code>[ThreadStatic]</code> field (because there's no guarantee the <code>Task</code> wouldn't be run on multiple threads (sequentially, obviously) or multiple <code>Task</code>s on a single thread (perhaps all blocking on I/O)).</p>