how do set a timeout for a method

前端 未结 8 1272
情书的邮戳
情书的邮戳 2020-12-25 15:10

how do set a timeout for a busy method +C#.

相关标签:
8条回答
  • 2020-12-25 16:07

    You can not do that, unless you change the method.

    There are two ways:

    1. The method is built in such a way that it itself measures how long it has been running, and then returns prematurely if it exceeds some threshold.
    2. The method is built in such a way that it monitors a variable/event that says "when this variable is set, please exit", and then you have another thread measure the time spent in the first method, and then set that variable when the time elapsed has exceeded some threshold.

    The most obvious, but unfortunately wrong, answer you can get here is "Just run the method in a thread and use Thread.Abort when it has ran for too long".

    The only correct way is for the method to cooperate in such a way that it will do a clean exit when it has been running too long.

    There's also a third way, where you execute the method on a separate thread, but after waiting for it to finish, and it takes too long to do that, you simply say "I am not going to wait for it to finish, but just discard it". In this case, the method will still run, and eventually finish, but that other thread that was waiting for it will simply give up.

    Think of the third way as calling someone and asking them to search their house for that book you lent them, and after you waiting on your end of the phone for 5 minutes you simply say "aw, chuck it", and hang up. Eventually that other person will find the book and get back to the phone, only to notice that you no longer care for the result.

    0 讨论(0)
  • 2020-12-25 16:09

    Ok, here's the real answer.

    ...
    
    void LongRunningMethod(object monitorSync)
    {
       //do stuff    
       lock (monitorSync) {
         Monitor.Pulse(monitorSync);
       }
    }
    
    void ImpatientMethod() {
      Action<object> longMethod = LongRunningMethod;
      object monitorSync = new object();
      bool timedOut;
      lock (monitorSync) {
        longMethod.BeginInvoke(monitorSync, null, null);
        timedOut = !Monitor.Wait(monitorSync, TimeSpan.FromSeconds(30)); // waiting 30 secs
      }
      if (timedOut) {
        // it timed out.
      }
    }
    
       ...
    

    This combines two of the most fun parts of using C#. First off, to call the method asynchronously, use a delegate which has the fancy-pants BeginInvoke magic.

    Then, use a monitor to send a message from the LongRunningMethod back to the ImpatientMethod to let it know when it's done, or if it hasn't heard from it in a certain amount of time, just give up on it.

    (p.s.- Just kidding about this being the real answer. I know there are 2^9303 ways to skin a cat. Especially in .Net)

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