Categle
Categle

Reputation: 514

Interrupt method execution on demand

I do have a method for which the execution time might take a while (approx. 2 minutes) running inside a task:

public Task BaseWorkerTask { get; set; }

public void Initialize()
{
    BaseWorkerTask = Task.Run(() => 
    {
        BaseWorker();
    });
}

public void BaseWorker()
{
    Server.Speak(Packet.Greeting);

    while (WaitServerResponse())
    {
        DoSomethingElse();
    }

    var response = Server.GetResponse();

    if (response.Equals("abc"))
    {
        DoAbcTask();
    }
    else if (response.Equals("def"))
    {
        [...]
    }

    [...]
}

I would like to be able to interrupt it's execution for a given period of time in order to do some other server calls. What is important to note here, is that I want it to "pause" script execution at current line in the BaseWorker method, just where it's exactly at.

Something like:

if (!BaseWorkerTask.IsCompleted)
{
    // Pause to do something else
    // BaseWorkerTask.StopAtCurrentPlace();

    DoSomethingElse();

    // Once something else is done, resume BaseWorkerTask
    // BaseWorkerTask.Resume();
}

Can such approach be achieved?

I have been trying to play with blocking a thread, however I was only able to block it once the method has finished using endless loop with System.Threading.Thread.Sleep(...).

Upvotes: 0

Views: 58

Answers (2)

Selman Genç
Selman Genç

Reputation: 101731

I would use some kind of a bool flag, similar to a cancellation token. Set it to true when you want to suspend execution of the task, and inside of the BaseWorker check the value of the variable at various places. If it's true, use Thread.Sleep to halt execution until it's set to false.

Example:

bool suspendExecution = false;

public void Initialize()
{
    BaseWorkerTask = Task.Run(() =>
    {
        BaseWorker(ref suspendExecution);
    });
}



public void BaseWorker(ref bool suspend)
{
    while (WaitServerResponse())
    {
         if (suspend)
         {
             while (suspend)
             {
                 Thread.Sleep(1000);
             }
         }

         DoSomethingElse();
     }
}

Upvotes: 0

spender
spender

Reputation: 120518

Thread.Suspend is probably the closest you'll get, but it's marked as obsolete with the following (relevant) warning:

Do not use the Suspend and Resume methods to synchronize the activities of threads. You have no way of knowing what code a thread is executing when you suspend it. If you suspend a thread while it holds locks during a security permission evaluation, other threads in the AppDomain might be blocked. If you suspend a thread while it is executing a class constructor, other threads in the AppDomain that attempt to use that class are blocked. Deadlocks can occur very easily.

In short, anything that can do this would be a bad idea for exactly the same reasons as above.

Attempting to use it on thread-pool threads virtually assures you of malfunction.

If you want to do this, you'll have to think of a way that the task can co-operate in its own pausing. Likely, this will involve peppering the code with synchronization stuff.

What's taking so long anyway?

Upvotes: 1

Related Questions