Thread timeout in c#

前端 未结 7 618
春和景丽
春和景丽 2021-01-11 18:41

I\'m new to threading in C#. Is there anyway of setting a timeout for a thread without blocking the calling thread (in C# 3.5)?

If not, is it logical to execute a fu

相关标签:
7条回答
  • 2021-01-11 19:26

    "Join member--> Blocks the calling thread until a thread terminates, while continuing to perform standard COM and SendMessage pumping." MSDN website.

    thrd1.Join() tell the calling thread to wait until the completion of the thrd1.

    My favorite solution is to make a small class which i'm able to control the execution of thread.

    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);
            }
       }
    
    0 讨论(0)
  • 2021-01-11 19:28

    You can start a System.Threading.Timer for each thread and pass it the thread's ManagedThreadId. Keep dictionaries for the active threads and their timers, keyed by the ManagedThreadId. If a timer expires, use the passed thread ID to abort the thread and kill its timer. If the thread finishes normally, invoke a callback that kills the timer. Here's a simple console example:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    
    namespace ConsoleApplication2
    {
        public delegate void KillTimerDelegate(int arg);
    
        class Program
        {
            static Dictionary<int, Thread> activeThreads = new Dictionary<int, Thread>();
            static Dictionary<int, Timer> activeTimers = new Dictionary<int, Timer>();
            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);
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-11 19:32

    You might also want to take a look at ThreadPool.QueueUserWorkItem() ( http://msdn.microsoft.com/en-us/library/kbf0f1ct.aspx ) which does a lot of stuff for you.

    As Brian commented, aborting a thread is usually not a smart thing to do, because it could be in the middle of doing some important stuff at that moment.

    0 讨论(0)
  • 2021-01-11 19:32

    The easiest thing to do is to call Thread.Join at safe points from your main thread and pass in the amount of time you want to wait for the join to occur.

    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.
      }
    }
    
    0 讨论(0)
  • 2021-01-11 19:38

    I checked and the simplest and most comprehensive way of doing it was the solution I mentioned in the description of the question. A middle level thread can easily wait for the second thread without any interruption over the main thread; and it can kill the second thread if it does not respond within the required time. That's exactly what I needed. I used it and it worked without a problem.

    0 讨论(0)
  • 2021-01-11 19:40

    See this: http://www.techtalkz.com/c-c-sharp/111717-thread-timeout.html

    Check out the TimeSpan method http://msdn.microsoft.com/en-us/library/23f7b1ct.aspx

    0 讨论(0)
提交回复
热议问题