c#中的线程超时

我是C#线程的新手。 有没有为线程设置超时而不阻塞调用线程(在C#3.5中)?

如果没有,使用线程执行函数是否合乎逻辑,并且在该函数内创建一个线程并加入它来克服这个主线程阻塞问题? 为了显示:

代替:

Public void main() { ... Thread thrd1 = new Thread(new ThreadStart(targetObj.targetFunc)); thrd1.Start(); thrd1.Join(); ... } 

使用类似的东西:

 Public void main() { ... Thread thrd1 = new Thread(new ThreadStart(middleObj.waiter)); thrd1.Start(); ... } //And in the middleObj.waiter(): Public void waiter() { Thread thrd2 = new Thread(new ThreadStart(targetObj.targetFunc)); thrd2.Start(); thrd2.Join(); } 

我检查过,最简单,最全面的方法就是我在问题描述中提到的解决方案。 中级线程可以轻松地等待第二个线程而不会中断主线程; 如果它在所需的时间内没有响应,它可以杀死第二个线程。 这正是我所需要的。 我用它,它没有问题。

您可以为每个线程启动System.Threading.Timer并将其传递给线程的ManagedThreadId。 保留活动线程及其计时器的字典,由ManagedThreadId键入。 如果计时器到期,请使用传递的线程ID中止线程并终止其计时器。 如果线程正常完成,则调用杀死计时器的回调。 这是一个简单的控制台示例:

 using System; using System.Collections.Generic; using System.Threading; namespace ConsoleApplication2 { public delegate void KillTimerDelegate(int arg); class Program { static Dictionary activeThreads = new Dictionary(); static Dictionary activeTimers = new Dictionary(); static void Main(string[] args) { for (int i = 0; i < 10; i++) { Worker worker = new Worker(); worker.DoneCallback = new KillTimerDelegate(KillTimer); Thread thread = new Thread(worker.DoWork); activeThreads.Add(thread.ManagedThreadId, thread); thread.IsBackground = true; thread.Start(); Timer timer = new Timer(TimerCallback, thread.ManagedThreadId, 500, 500); activeTimers.Add(thread.ManagedThreadId, timer); } Console.ReadKey(); } static void TimerCallback(object threadIdArg) { int threadId = (int)threadIdArg; if (activeThreads.ContainsKey(threadId)) { Console.WriteLine("Thread id " + threadId.ToString() + " aborted"); activeThreads[threadId].Abort(); KillTimer(threadId); } } static void KillTimer(int threadIdArg) { activeThreads.Remove(threadIdArg); activeTimers[threadIdArg].Dispose(); activeTimers.Remove(threadIdArg); } } public class Worker { public KillTimerDelegate DoneCallback { get; set; } Random rnd = new Random(); public void DoWork() { Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString() + " started"); Thread.Sleep(rnd.Next(0, 1000)); Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString() + " finished normally"); DoneCallback(Thread.CurrentThread.ManagedThreadId); } } } 

您可能还想看看ThreadPool.QueueUserWorkItem()http://msdn.microsoft.com/en-us/library/kbf0f1ct.aspx ),它为您做了很多事情。

正如布莱恩所评论的那样,中止线程通常不是一件明智的事情,因为在那一刻它可能正在做一些重要的事情。

见: http : //www.techtalkz.com/cc-sharp/111717-thread-timeout.html

查看TimeSpan方法http://msdn.microsoft.com/en-us/library/23f7b1ct.aspx

最简单的方法是在主线程的安全点调用Thread.Join ,并传入您希望等待连接发生的时间。

 public static void Main() { TimeSpan timeout = TimeSpan.FromSeconds(30); Thread thread = new Thread(() => { ThreadMethod(); }); thread.Start(); DateTime timeStarted = DateTime.UtcNow; DoSomeWorkOnThisThread(); // We are at a safe point now so check the thread status. TimeSpan span = DateTime.UtcNow - timeStarted; // How long has the thread been running. TimeSpan wait = timeout - span; // How much more time should we wait. if (!thread.Join(wait)) { thread.Abort(); // This is an unsafe operation so use as a last resort. } } 

“Join member – >阻塞调用线程,直到线程终止,同时继续执行标准COM和SendMessage抽取。” MSDN网站。

thrd1.Join()告诉调用线程等到thrd1完成。

我最喜欢的解决方案是创建一个小类,我能够控制线程的执行。

 public class MyClass { private bool _stop; private Thread _myThread; public void Stop() { _stop = true; //Will block the calling thread until the thread die _myThread.Join(); } public void Run() { _stop = false; _myThread = new Thread(Work); } public void Work() { do { } while (!_stop); } } 

使用middleObject方案查看WaitHandle.WaitOne()方法。

 Public void main() { ... middleObj.WaitHandle.Reset(); Thread thrd1 = new Thread(new ThreadStart(middleObj.waiter)); thrd1.Start(); middleObj.WaitHandle.WaitOne(timeout); ... } //And in the middleObj.waiter(): Public void waiter() { Thread thrd2 = new Thread(new ThreadStart(targetObj.targetFunc)); thrd2.Start(); thrd2.Join(); this.WaitHandle.Set(); } 

但不确定未完成的线程会发生什么。