0

我需要监视一个任务,如果它花费的时间超过定义的超时时间,就将其终止。

到目前为止,我做了很多尝试,从创建线程和发出线程中止等开始。然后,我决定使用 TPL。

您必须假设 WorkItem 是一个黑匣子。您无权访问其源代码。因此,重写它以使其跟踪令牌是不现实的。这需要从外部控制。

有任何想法吗?

  public class WorkItem : IDisposable
  {
    private System.Diagnostics.Stopwatch _watch = new System.Diagnostics.Stopwatch();
    private List<string> _messages = new List<string>();

    public void WriteMessage(string message)
    {
      _messages.Add(message);
    }

    public void Run()
    {
      for (int i = 1; i <= 25; i++)
      {
        System.Threading.Thread.Sleep(1000);
        Console.WriteLine("Slept one second after {0} iteration.", i);
      }
    }

    public void Dispose()
    {
      _watch.Stop();
      Console.WriteLine("Disposed... lived for {0} milliseconds", _watch.ElapsedMilliseconds);
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      int timeout = 5000;
      WorkItem item = new WorkItem();
      System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Factory.StartNew<WorkItem>((arg) =>
      {
        WorkItem currentWorkItem = arg as WorkItem;
        currentWorkItem.Run();
        return currentWorkItem;
      }, item);

      bool wait = task.Wait(timeout);
      if (wait == false)
      {
        Console.WriteLine("It took more than {0} ms.", timeout);
        // Need a way to kill the task.
      }

      Console.WriteLine("Okay Waiting");
      Console.ReadKey();
    }
  }
4

1 回答 1

3

Task您无法从外部取消它是有原因的。当你有一个黑匣子在运行时,当你杀死它时,不知道它会做什么。它可能持有锁。它可能正在修改某些共享状态。它可能正在做任何数量的事情,如果被中断,将使您的程序处于未知且很可能已损坏的状态。中止线程就像关闭计算机的电源开关。没有人知道你可能会破坏什么。

我强烈反对我将要提出的建议,但如果你真的必须在死亡或失去工作的痛苦中向自己开枪...... errrr,让你的程序能够杀死你的黑匣子,然后做它用一根线。

WorkItem threadResult = null;
Thread t = new Thread((arg) =>
    WorkItem currentWorkItem = arg as WorkItem;
    currentWorkItem.Run();
    threadResult = currentWorkItem;
  }, item);

// wait for thread to exit
bool done = t.Join(timeout);            
if (!done)
{
    t.Abort();
}

再一次,我对您因使用此技术而可能遇到的任何负面后果不承担任何责任。中止线程几乎总是会给你带来麻烦。

于 2013-07-19T20:14:08.737 回答