Prasad Kanaparthi
Prasad Kanaparthi

Reputation: 6563

How to cancel the thread after timeout

I have a multi-threaded application and i'm using this to control the no.of processes (2). I want to process files only for specified time duration. Below is my approach. I'm getting The CancellationTokenSource has been disposed. error.

If i'm not dispoing the cts.Dispose(); then the process is not stooping after 10 sec. It is keep on processing till 1000. Can any one help me here.

Note: I've a 1000 files. Requirement is process files with in a given time (10 sec) by controlling the number of process (2) and sleep in between (some x ms).

Below is my code

class Program
{
    static void Main(string[] args)
    {
        try
        {
            LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(2);
            List<Task> tasks = new List<Task>();
            TaskFactory factory = new TaskFactory(lcts);
            CancellationTokenSource cts = new CancellationTokenSource();

            for (int i = 0; i < 1000; i++)
            {
                int i1 = i;
                var t = factory.StartNew(() =>
                {
                    if (cts != null)
                        Console.WriteLine("{0} --- {1}", i1, GetGuid(cts.Token));
                }, cts.Token);

                tasks.Add(t);
            }

            Task.WaitAll(tasks.ToArray(), 10000, cts.Token);
            cts.Dispose();
            Console.WriteLine("\n\nSuccessful completion.");
            Console.ReadLine();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

    private static Guid GetGuid(CancellationToken cancelToken)
    {
        if (cancelToken.IsCancellationRequested)
        {
            return Guid.Empty;
        }
        Thread.Sleep(TimeSpan.FromSeconds(1));
        return Guid.NewGuid();
    }
}

Upvotes: 1

Views: 463

Answers (1)

Fabjan
Fabjan

Reputation: 13676

What you can do is you can run a Task that will change your Cancellation Token state to canceled after some time.

Like this :

class Program
{
    public static void ProcessFiles(CancellationToken cts)
    {            
        try
        {                
            LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(2);
            List<Task> tasks = new List<Task>();
            TaskFactory factory = new TaskFactory(lcts);                

            for (int i = 0; i < 1000; i++)
            {
                int i1 = i;
                var t = factory.StartNew(() =>
                {
                    if (cts != null) Console.WriteLine("{0} --- {1}", i1, GetGuid());
                }, cts);

                tasks.Add(t);
            }

            Task.WaitAll(tasks.ToArray());

            Console.WriteLine("\n\nSuccessful completion.");
            Console.ReadLine();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

    static void Main(string[] args)
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        Task.Factory.StartNew(() => { Thread.Sleep(10000); cts.Cancel(); });
        ProcessFiles(cts.Token);
        Console.ReadKey();
    }

    private static Guid GetGuid()
    {
        Thread.Sleep(TimeSpan.FromSeconds(1));
        return Guid.NewGuid();
    }
}

Upvotes: 1

Related Questions