none
multithreading with timeout

    Question

  • Hello all,

    my requirement is like below;

    i have one function which contains no. of tasks and no. of thread (function (var noOftasks,var noOfThread)); which will be called from outside or say from another app.

    when this function calls i create noOfthread and assign task to each thread one by one, if all thread is busy then wait for any thread to be free and then again assign task( if any remaining) to it.

    now i also want to set timeout that if any thread running out of time then it will be aborted

    because main thread is working continously to check free thread and assign task, i can not rely on Thread.Join(timeout) and make thread aborted according to that.

    how can i achieve same? below is code snippet
    public class TaskA
    {
    
        public List<TaskProcess> ProcessTasks(List<TaskProcess> ListOfTaskProcess, int NoOfThreads)
        {
            try
            {
                Thread[] _threadPool = new Thread[NoOfThreads];
    
                foreach (var _task in ListOfTaskProcess)
                {
                    Thread _Thread = null;
    
                    while (true)
                    {
                        _Thread = GetFreeThread(_threadPool);
    
                        if (_Thread != null)
                        {
                            break;
                        }
                        else
                        {
                            Thread.Sleep(1000);
                        }
                    }
    
                    if (_Thread != null)
                    {                    
                        _Thread.Start(_task);
                    }
                }
    
                foreach (var _Thread in _threadPool)
                {
                    if (_Thread.IsAlive)
                    {
                        _Thread.Join();
                    }
                }
    
                return ListOfTaskProcess;
            }
            catch (Exception)
            {
                return ListOfTaskProcess;
            }
        }
    
        private Thread GetFreeThread(Thread[] p_ThreadPool)
        {
            try
            {
                foreach (var _thread in p_ThreadPool)
                {
                    if (_thread == null || (_thread.IsAlive == false && _thread.ThreadState != ThreadState.Running))
                    {
                        return new Thread(doTask);
                    }
                }
    
                return null;
            }
            catch (Exception _Exception)
            {
                
            }
        }
    
        private void doTask(object _task)
        {
            try
            {
                _task.status = "In Progress";
    
                /* do task process here*/
    
                _task.status = "completed";                
            
            }
            catch (Exception _Exception)
            {
                _task.status = "Failed";
            }
        }
    
        public class TaskProcess
        {
            /* other properties */
            public string status { get; set; }
        }
    }
    


    please help me to do it.

     

    Thanks,

    Vishal Parekh

    Wednesday, January 18, 2012 11:06 AM

Answers

  • Hi Vishal,

       I will use WaitHandler, and ManualResetEvent, something like the following....

       it doesn't control the timeout of each single thread, but it just control the overall time. the waithandler will wait all the waithandler to get a signal for 60 seconds, if it timeout, then it will move on..

    public class TaskItem

        {

            private ManualResetEvent _mre = null;

            public TaskItem(ManualResetEvent mre)

            {

                _mre = mre;

            }

            public void DoTask()

            {

                Console.writeline("Do task");

                Thread.sleep(1000);

                _mre.set();

            }

        }

     

        public class MainClass

        {

            public MainClass()

            {

     

            }

            public void DoTest()

            {

                var lst = new List<TaskItem>();

                var lstRestEvent = new List<ManualResetEvent>();

                for (int i = 0; i < 10; i++)

                {

                    var re = new ManualResetEvent();

                    var ti = new TaskItem(re);

                    lst.add(ti);

                    lstResetEvent.add(re);

                    ThreadPool.QueueWorkItems(ti.DoTask);

                }

                //Wait all the thread to exit for 60 seconds.

                WaitHandler.WaitAll(lstResetEvent.ToArray(),60*1000);

            }

        }

        Hope this can meet your requirement.

     


    Johnny
    Thursday, January 19, 2012 12:40 PM

All replies

  • instead of managing the thread by yourself, i will suggest you to use the ThreadPool that comes with the .net framework.

    The only thing you do is just queue work items, then the thread pool will schedule it to execute. 

    http://msdn.microsoft.com/en-us/library/3dasc8as(v=VS.80).aspx


    Johnny
    Wednesday, January 18, 2012 11:58 AM
  • Thanks Johnny,

    yes threadpool is better,

    but how can i set timeout for each thread? ; as i want that after particular time if thread is not completed then i need to abort that thread .

    i change above code snippet; i use Timer to make timeout for each thread

     

    .....
    
     if (_Thread != null)
     {
    
                            TimerCallback tcb = AbortThread;
    
                            Timer _Timer = new Timer(tcb, _Thread, ThreadTimeOut, Timeout.Infinite);
    
                            _Thread.Start(_task);
     }
    
      private static void AbortThread(object _Thread)
            {
                try
                {
                       if (_Thread.IsAlive)
                       {
                           _Thread.Abort();
                       }
                 }
                 catch(Exception)
                 {
            
                  }
            }
    


    is it proper way to do it?

     

    Thanks,

    Vishal Parekh

     

     

    Thursday, January 19, 2012 6:45 AM
  • Hi Vishal,

       I will use WaitHandler, and ManualResetEvent, something like the following....

       it doesn't control the timeout of each single thread, but it just control the overall time. the waithandler will wait all the waithandler to get a signal for 60 seconds, if it timeout, then it will move on..

    public class TaskItem

        {

            private ManualResetEvent _mre = null;

            public TaskItem(ManualResetEvent mre)

            {

                _mre = mre;

            }

            public void DoTask()

            {

                Console.writeline("Do task");

                Thread.sleep(1000);

                _mre.set();

            }

        }

     

        public class MainClass

        {

            public MainClass()

            {

     

            }

            public void DoTest()

            {

                var lst = new List<TaskItem>();

                var lstRestEvent = new List<ManualResetEvent>();

                for (int i = 0; i < 10; i++)

                {

                    var re = new ManualResetEvent();

                    var ti = new TaskItem(re);

                    lst.add(ti);

                    lstResetEvent.add(re);

                    ThreadPool.QueueWorkItems(ti.DoTask);

                }

                //Wait all the thread to exit for 60 seconds.

                WaitHandler.WaitAll(lstResetEvent.ToArray(),60*1000);

            }

        }

        Hope this can meet your requirement.

     


    Johnny
    Thursday, January 19, 2012 12:40 PM