locked
Pausing a Task.. RRS feed

  • Question

  • Hello,

    I have a long executing Task which I'd want to pause/resume. Basically i'd like a button with which the user pauses/resumes the task.

    I've tried ManualResetEvent and all sorts of stuff..

    Any suggestions?

    Thursday, February 16, 2012 5:10 PM

Answers

  • The Monitor class (which is what lock uses) makes a simple way to handle this.  You can have a synchronization object, and enter/exit the "lock" as needed to pause your processing, ie:

    private object syncObj = new object(); // For locking...
    private bool paused;
    
    // For the method that does your long running task...
    private void LongRunningTask()
    {
        //... Somewhere, you have a loop or something that's processing...
        while(processing)
        {
            // This will make sure that it shouldn't "pause"
            // When in "paused" state (see below), it'll
            // freeze here and not continue
            lock(syncObj) {}
    
            // Do your work...
        }
    }
    
    
    private void Pause()
    {
        if (paused == false)
        {
            // This will acquire the lock on the syncObj,
            // which, in turn will "freeze" the loop
            // as soon as you hit a lock(syncObj) statement
            Monitor.Enter(syncObj);
            paused = true;
        }
    }
    
    private void Resume()
    {
        if (paused)
        {
            paused = false;
            // This will allow the lock to be taken, which will let the loop continue
            Monitor.Exit(syncObj);
        }
    }


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Proposed as answer by servy42 Thursday, February 16, 2012 5:45 PM
    • Marked as answer by Bob Shen Wednesday, February 29, 2012 3:31 AM
    Thursday, February 16, 2012 5:28 PM
  • Create a new thread, and execute the code (of your tasks) in it.  You can even use Backgroundworker class to pause it.

    Here are some helpful links:

    http://stackoverflow.com/questions/142826/is-there-a-way-to-indefinitely-pause-a-thread

    http://stackoverflow.com/questions/8359058/pause-resume-loop-in-background-worker


    Mitja

    • Marked as answer by Bob Shen Wednesday, February 29, 2012 3:31 AM
    Thursday, February 16, 2012 5:16 PM

All replies

  • Create a new thread, and execute the code (of your tasks) in it.  You can even use Backgroundworker class to pause it.

    Here are some helpful links:

    http://stackoverflow.com/questions/142826/is-there-a-way-to-indefinitely-pause-a-thread

    http://stackoverflow.com/questions/8359058/pause-resume-loop-in-background-worker


    Mitja

    • Marked as answer by Bob Shen Wednesday, February 29, 2012 3:31 AM
    Thursday, February 16, 2012 5:16 PM
  • The Monitor class (which is what lock uses) makes a simple way to handle this.  You can have a synchronization object, and enter/exit the "lock" as needed to pause your processing, ie:

    private object syncObj = new object(); // For locking...
    private bool paused;
    
    // For the method that does your long running task...
    private void LongRunningTask()
    {
        //... Somewhere, you have a loop or something that's processing...
        while(processing)
        {
            // This will make sure that it shouldn't "pause"
            // When in "paused" state (see below), it'll
            // freeze here and not continue
            lock(syncObj) {}
    
            // Do your work...
        }
    }
    
    
    private void Pause()
    {
        if (paused == false)
        {
            // This will acquire the lock on the syncObj,
            // which, in turn will "freeze" the loop
            // as soon as you hit a lock(syncObj) statement
            Monitor.Enter(syncObj);
            paused = true;
        }
    }
    
    private void Resume()
    {
        if (paused)
        {
            paused = false;
            // This will allow the lock to be taken, which will let the loop continue
            Monitor.Exit(syncObj);
        }
    }


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Proposed as answer by servy42 Thursday, February 16, 2012 5:45 PM
    • Marked as answer by Bob Shen Wednesday, February 29, 2012 3:31 AM
    Thursday, February 16, 2012 5:28 PM
  • What didn't work with the ManualResetEvent?
    Thursday, February 16, 2012 5:42 PM
  • What didn't work with the ManualResetEvent?

    Jared,


    While I don't know (I didn't write the code, of course!), it's actually tricky to get a ManualResetEvent to pause a different thread.  The problem is that it works by calling WaitOne()/Set() - which makes it easy to pause the current thread, and resume it from a different place, but you can't easily start/stop a thread from "outside" using a wait handle.  (There are approaches, but it's quite convoluted, and I'd argue that Monitor is a much cleaner method of handling this situation) 


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Thursday, February 16, 2012 5:57 PM