Search code examples
c#eventsc#-4.0task-parallel-libraryblocking

Pause task execution


I have a long running task that behaves like a transaction - it involves many operations where success of one depends on success of another.

class MyTransaction
{
    public void Execute()
    {
        StopServices();
        BackupFiles();
        OverwriteFiles();
        BackupDatabases();
        RunChangeScripts();
        ... and few others        
    }

    public void RollBack() { }
}

class MyTransactionManager
{
    public RunTransactions()
    {
        Task.Factory.StartNew(() => {
            new MyTransaction().Execute();
        });
    }
}

This is just a pseudo-code of the real application where different operations are provided by different components of the system. There is an underlying GUI (WinForms) that displays progress using a progress bar and few other thing that have to stay responsive no matter what happens. Transactions are all really long running so there is no need to specify it when starting tasks (using TaskCreationOptions), it always runs in a new thread. Progress from transactions is reported back to the GUI using events.

Now, there is a request that if something during execution of a transaction fails it won't immediately roll back as it currently does. They want to pop up a message box in the GUI giving a user an option to decide whether to roll back or fix the error and continue from the last successful point.

So I need somehow implement a blocking. I thought that I could just raise another event, pop up a message box and say "Hey, fix it and then press ok". And bind that OK click event to my outer manager (public API) which can delegate requests directly to my transactions. And blocking would just actively run a while loop checking some bool property.

Now I am thinking that passive blocking would be better but I don't really know how to do it. Could you please advise me?

EDIT: And I don't really want to use Thread.Sleep, because these errors can take various time to fix. Depends on an error and a person who is fixing it.


Solution

  • And blocking would just actively run a while loop checking some bool property.

    That's not blocking, it's called busy waiting and it's something you should avoid.

    If you want to have synchronization like this between two threads, one way is to use ManualResetEvent:

    AskUser(); // doesn't block
    shouldRollbackEvent.WaitOne();
    if (shouldRollback) …
    

    And on your UI thread:

    shouldRollback = …;
    shouldRollbackEvent.Set();
    

    (This assumes both parts of the code execute within the same object.)