Share via


Monitor and Abort/Kill a thread if its taking too long (how to do it?)

Question

Wednesday, October 27, 2010 4:44 AM

Hi,

I was wondering about monitoring and killing a thread if it is processing something for lets say more than 5 mins.

I know about the abort method but dont really know how to monitor the thread. following is a situation which has multithreading and synchronization.

private void StartThreads(DataTable pDataTable)
{
   for(int i = 0; i < pDataTable.Rows.Count; i++)
   {
     ThreadPool.QueueUserWorkItem(new WaitCallback(ExecutionStartOnThread), pDataTable.Rows[i]);
    }
}

private void ExecutionStartOnThread(DataRow pDr);
{
  /*long running logic
   may have some method that might take more time than expected*/
  Monitor.Enter(_Obj);
  try
  {
  //some long running method requiring synchronization
  }
  finally
 {
   Monitor.Exit(_Obj);
 }
}

so, the first question would be how to kill this threadpool thread.

And if at all one is successful in killing a thread which has passed into critical section after Monitor.Enter, how to ensure that the Monitor.Exit for that thread gets executed.

Kindly respond, if anyone has implemented or has any about it.

 

Regards,

Ameet More

Regards, Ameet More

All replies (6)

Wednesday, October 27, 2010 2:07 PM ✅Answered

http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx

"There is no way to cancel a work item after it has been queued."

What you can do is start another thread and wait for it to finish with a timeout value:

private void ExecutionStartOnThread(DataRow pDr)
{
  lock(_Obj)
  {
    ManualResetEvent wait = new ManualResetEvent(false);
    Thread work = new Thread(new ThreadStart(() =>
    {

      //some long running method requiring synchronization

      wait.Set();
    }));
    work.Start();
    wait.WaitOne(300000);
    if (work.IsAlive) work.Abort();
  }
}

Wednesday, October 27, 2010 6:24 PM ✅Answered

Hello,

 

You can make a routine that abort your thread after 5 min or any value. In this example, I put 10 seconds in timeout :

 

using System;
using System.Threading;


namespace Test.ThreadAbort
{
  class Program
  {
    // killing the thread after [ThreadTimeout], you can put 5min or any value
    static TimeSpan ThreadTimeout = new TimeSpan(0, 0, 10);
    // oThread start date
    static DateTime ThreadStartDate;
    // thread killer after the timeout
    static Thread ThreadTimeoutKiller = new Thread(new ParameterizedThreadStart(KillThreadAfterTimeout));

    static void DoWork()
    {
      try
      {
        ThreadStartDate = DateTime.Now;

        for (; ; )
        {
          Console.WriteLine("I am working !");
          Thread.Sleep(500);
        }
      }
      catch (ThreadAbortException)
      {
        Console.WriteLine("I am aborted !");
      }

    }

    static void KillThreadAfterTimeout(object oThread)
    {
      // Kill the thread after ThreadTimeout TimeSpan
      for (; ; )
      {
        if (DateTime.Now > ThreadStartDate.AddTicks(ThreadTimeout.Ticks) && ((Thread)oThread).IsAlive)
        {
          ((Thread)oThread).Abort();
        }

        if (!((Thread)oThread).IsAlive)
        {
          break;
        }

        Thread.Sleep(500);

      }
    }

    static void Main(string[] args)
    {
      Thread oThread = new Thread(DoWork);
      oThread.Start();
      ThreadTimeoutKiller.Start(oThread);

      Console.ReadLine();
    }

  }
}

Regards,


Wednesday, October 27, 2010 7:00 PM ✅Answered

Hello,

 

If you are on .NET 4 you can use TaskFactory . in order to create tasks, cancel them.

Even better you can also specify that it is a long running task so the task will not be created on a thread from the current thread pool.

An example of usage can be found here .

 

If you are not on .net 4 i would suggest a background worker with periodical checks for cancelation requests, this way you could even save the state and resume the operation without creating a new thread.

 

Hope this helps, if you have any other questions or comments, please let me know,

Best Regards,
Emanuel Varga

 

 

 

If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".


Wednesday, October 27, 2010 8:55 AM

Instead of killing the thread, set a flag and check the flag inside the long running method. Return gracefully from the thread method when the flag is set.


Wednesday, October 27, 2010 9:36 AM

hi,

 

Thank you for the suggestion, but if the long running operation is a call to some unmanaged dlls and if the thread is taking more time than usual and yet its not finishing the execution i.e. if the thread is hanging over there then how to go about it.

Kindly support with an example for me to understand better.

 

Regards, Ameet More


Wednesday, October 27, 2010 6:29 PM

private
 void
 StartThreads(DataTable pDataTable)
{
  for
(int
 i = 0; i < pDataTable.Rows.Count; i++)
  {
   ThreadPool.QueueUserWorkItem(new
 WaitCallback(ExecutionStartOnThread), pDataTable.Rows[i]);
  }
}

private
 void
 ExecutionStartOnThread(DataRow pDr);
{
 /*long running logic
  may have some method that might take more time than expected*/

 Monitor.Enter(_Obj);
 try

 {
 //some long running method requiring synchronization

 }
 finally

 {
  Monitor.Exit(_Obj);
 }
}

In addition to what the others have posted, I note that you are seemingly trying to spawn the processing of EACH data row onto it's own thread.  Yet they all lock on the same object, so they will end up executing sequentially.  You are not actually getting multithreading out of them (other than getting them off the calling thread).