This is how I would do it:
- Have a
connection
variable somewhere initially set tonull
. - Whenever an item is processed,
connection
is created if needed and then used. - After the block is completed (which you can find out using the
Completed
property, assuming you propagate completion properly),Dispose()
the connection, if it has been created.
In code, as a helper method, it could look something like this:
public static TransformBlock<TInput, TOutput>
CreateTransformBlockWithConnection<TInput, TOutput, TConnection>(
Func<TInput, TConnection, TOutput> transform,
Func<TConnection> connectionFactory)
where TConnection : class, IDisposable
{
TConnection connection = null;
var block = new TransformBlock<TInput, TOutput>(
input =>
{
if (connection == null)
connection = connectionFactory();
return transform(input, connection);
});
block.Completion.ContinueWith(
_ =>
{
if (connection != null)
connection.Dispose();
});
return block;
}
(Note that this won't behave correctly if connectionFactory
ever returns null
. If you're worried about that, you can add a check for it.)
Usage example (this executes each string input as a SQL command and returns the result):
var block = CreateTransformBlockWithConnection(
(string input, SqlConnection connection) =>
new SqlCommand(input, connection).ExecuteScalar(),
() => new SqlConnection());