6

Is there a way to set a value for how long a thread should (maximally) be alive when you start the thread?

Said in another way, with "pseudocode", is there anything like this:

Thread t = new Thread();
t.start();
t.abort_after_x_seconds(30);

which would make the thread abort if it lived more than 30 seconds.

Edit: I still can't get it to work, what I originally had is:

while(true)
{
    if(...)
    {
        Thread t = new Thread(new ThreadStart(startMethod));
        t.start();
    }
    Thread.sleep(...);
}

the problem is that sometimes the threads will hang (I'm not implementing what the threads do so I don't know exactly why (it's a school project, we're noobs at organizing)), so I want to kill those threads. I tried using Tasks and CancellationTokens as in the examples below, but when the Task hangs it can't check if a cancellation request has occured.

user2817012
  • 261
  • 2
  • 11
  • 4
    That is not a good practice to abort a thread (Thread.Abort() has been deprecated, and does not work in any situations)... why would you like to do that ? There must be a good pattern to use instead of that. – Olivier Nov 11 '13 at 14:16
  • 1
    Is there some long action that you're doing inside the thread? If so, is it a possibility to set a timeout on that action instead? – Jeff B Nov 11 '13 at 14:17
  • Which context you're trying to use this feature? Provide more context. It is important what that thread is going to execute. – Sriram Sakthivel Nov 11 '13 at 14:17

3 Answers3

8
  1. Most of the time, you shouldn't be using Threads, use Tasks instead. They are more convenient and more efficient.
  2. Aborting something is not safe, you should use cooperative cancellation instead. If you're calling a method that supports cancellation, then just pass it a cancellation token that will be cancelled after 30 seconds.

So your code could look like this (using .Net 4.5):

var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)));
var task = Task.Run(() => YourMethod(cts.Token), cts.Token);
svick
  • 236,525
  • 50
  • 385
  • 514
  • much better :) however, even if you cancel your task - you need to make sure that the operation you are doing is gracefully aborted/cancelled – Ahmed ilyas Nov 11 '13 at 14:26
  • @Ahmedilyas That's the job of the called method, not of the caller. – svick Nov 11 '13 at 14:28
1

[EDIT: My response was far too slow. But I'll leave this here for the sample code.]

You should use co-operative cancellation for this purpose. The thread itself will need to detect when it should exit, and respond appropriately.

There's a thing called a CancellationToken produced from a CancellationTokenSource that you can use for this purpose.

There's even a CancellationTokenSource constructor which lets you set a timeout.

Here's some sample code to demonstrate its use:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace Demo
{
    class Program
    {
        private void run()
        {
            using (var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30)))
            {
                var task = Task.Run(() => exampleOne(tokenSource.Token));
                task.Wait();
            }

            using (var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30)))
            {
                var task = Task.Run(() => exampleTwo(tokenSource.Token));
                task.Wait();
            }

            Console.WriteLine("Done.");
        }

        static void exampleZero()
        {
            Console.WriteLine("Starting exampleZero()");

            try
            {
                Thread.Sleep(10000); // Simulate work.
            }

            catch (OperationCanceledException)
            {
                Console.WriteLine("Operation cancelled.");
            }

            Console.WriteLine("Exiting exampleZero()");
        }

        static void exampleOne(CancellationToken cancellation)
        {
            Console.WriteLine("Starting exampleOne()");

            // Busy loop processing.

            while (!cancellation.IsCancellationRequested)
            {
                // Do some work.
            }

            Console.WriteLine("Exiting exampleOne()");
        }

        static void exampleTwo(CancellationToken cancellation)
        {
            Console.WriteLine("Starting exampleTwo()");

            while (!cancellation.WaitHandle.WaitOne(100)) // Wait 100ms between work.
            {
                // Do some work.
            }

            Console.WriteLine("Exiting exampleTwo()");
        }

        static void Main()
        {
            new Program().run();
        }
    }
}
Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
0

As commenters have said, using Abort is bad practice and not guaranteed to abort immediately. Why would you want to keep the thread alive? The thread will be released back to the pool when the task assigned to it is completed. The next time the task is run on the thread will automatically be given from the pool of threads either by creating another new one or re-using one that is available in the threadpool.

Sounds like your logic/code is bad and needs to be fixed rather than waiting for something for x seconds then terminating it, which in itself will cause knock on problems.

Perhaps you need a timer instead which can tick after 30 seconds then you can disable the timer and kill the task at hand.

Jerska
  • 11,722
  • 4
  • 35
  • 54
Ahmed ilyas
  • 5,722
  • 8
  • 44
  • 72
  • 1
    Any resource saying `Abort` is deprecated? – Sriram Sakthivel Nov 11 '13 at 14:24
  • @SriramSakthivel [Is this thread.abort() normal and safe?](http://stackoverflow.com/q/421389/41071) – svick Nov 11 '13 at 14:25
  • @SriramSakthivel = my apologies. I edited my comment, as I was thinking else at the same time. it is not deprecated but not a good practice either. http://msdn.microsoft.com/en-us/library/ty8d3wta(v=vs.110).aspx – Ahmed ilyas Nov 11 '13 at 14:26
  • @svick - right. sorry, I was using the thread in a different context (damn English vs programming English) – Ahmed ilyas Nov 11 '13 at 14:28
  • `Thread.Abort` is not deprecated and while aborting threads certainly has issues and should not be done without consideration frameworks like ASP.NET is actually built around aborting threads to end a request. – Martin Liversage Nov 11 '13 at 14:29
  • @svick I know enough about `Abort` is evil. But safe/unsafe is far away from deprecated is my point – Sriram Sakthivel Nov 11 '13 at 14:35