I have a class that saves logging information to the database (in an NServiceBus message Handle
method).
Most of the time that logging can be done on a separate thread (and transaction) from the main process. But it all needs to be done on the same background thread (meaning that they have to be done in order, just not in sync with the main process).
However, once it starts Foreign Keying to the actual data from NServiceBus, it needs to be on the same thread.
Here is some example code:
public class MyExample
{
public void LogSomeStuff(Stuff stuff)
{
using (MoveOutsideTransaction())
{
// Do Method Stuff here
dataAccess.SaveChanges();
}
}
public void LogSomeOtherStuff(Stuff stuff)
{
using (MoveOutsideTransaction())
{
// Do Other Method Stuff here
dataAccess.SaveChanges();
}
}
private IDisposable MoveOutsideTransaction()
{
if (loggingOutsideTransaction)
return new TransactionScope(TransactionScopeOption.Suppress);
return null;
}
}
I am wondering if there is a way to use my transaction conditional to also conditionally move the running to a different thread. (But only when it suppresses the transaction.)
I am wondering if there is a way to use my transaction conditional to also conditionally move the running to a different thread.
You cannot just move the execution of a method onto a different thread. Threads do not work that way in general. However, what you can do is setup a dedicated thread that can participate in a marshaling operation which does, more or less anyway, simulate the transfer of execution to another thread. It is important to drive home the point that this dedicated thread must be specially coded to accept this marshaling operation.
Here is how it works.
public class DedicatedThread
{
private BlockingCollection<Action> actions = new BlockingCollection<Action>();
public DedicatedThread()
{
var thread = new Thread(
() =>
{
while (true)
{
Action action = actions.Take();
action();
}
});
}
public void SubmitAction(Action action)
{
actions.Add(action);
}
}
And you might use it like this.
if (loggingOutsideTransaction)
{
// Execute asynchronously on a dedicated thread.
dedicatedThread.SubmitAction(yourActionDelegate);
}
else
{
// Execute synchronously.
yourActionDelegate();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With