启动时设置线程生存期

时间:2013-11-11 14:14:39

标签: c# multithreading lifecycle

有没有办法设置启动线程时线程应该(最大)存活多长时间的值?

用另一种方式说,用“伪代码”,有这样的东西:

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

如果线程超过30秒,会使线程中止。

编辑:我仍然无法让它工作,我原来的是:

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

问题是有时候线程会挂起(我没有实现线程所做的事情,所以我不确切知道为什么(这是一个学校项目,我们是组织的新手))所以我想要杀死那些线程。我尝试使用Tasks和CancellationTokens,如下例所示,但当任务挂起时 它无法检查是否发生了取消请求。

3 个答案:

答案 0 :(得分:7)

  1. 大多数情况下,您不应该使用Thread,而是使用Task。它们更方便,更有效率。
  2. 中止某些内容并不安全,您应该使用合作取消。如果您正在调用支持取消的方法,那么只需传递一个取消令牌,该令牌将在30秒后被取消。
  3. 所以你的代码看起来像这样(使用.Net 4.5):

    var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)));
    var task = Task.Run(() => YourMethod(cts.Token), cts.Token);
    

答案 1 :(得分:1)

[编辑:我的反应太慢了。但我会在这里留下示例代码。]

您应该为此目的使用合作取消。线程本身需要检测何时应该退出,并做出适当的响应。

有一个叫CancellationTokenCancellationTokenSource来自CancellationTokenSource,可用于此目的。

甚至有一个{{3}}构造函数可以让你设置超时。

以下是一些展示其用途的示例代码:

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();
        }
    }
}

答案 2 :(得分:0)

正如评论者所说,使用Abort是不好的做法,不能保证立即中止。 为什么要保持线程活着?分配给它的任务完成后,该线程将被释放回池中。下一次在线程上运行任务时,将通过创建另一个新线程或重新使用线程池中可用的线程来自动从线程池中获得该任务。

听起来你的逻辑/代码很糟糕,需要修复而不是等待x秒然后终止它,这本身就会导致问题。

也许您需要一个可以在30秒后打勾的计时器,然后您可以禁用计时器并终止手头的任务。