как действительно устанавливают тайм-аут для метода

Одно из ключевых понятий, которым я всегда остаюсь верным, к , связанный с фиксацией код изменяется вместе . Заключение , не фиксируют несвязанных изменений кода в той же фиксации . Это означает, не исправляют 2 ошибки в одной фиксации (если это не то же, фиксируют), и не фиксируйте половину исправления ошибки в каждой из 2 фиксаций. Кроме того, если я должен добавить некоторое новое улучшение или что-то к несвязанной части системы, в которой я тогда нуждаюсь для некоторой другой работы, я фиксирую улучшение отдельно (и сначала). Идея состоит в том, что любое изменение, которое любой мог бы очевидно хотеть иметь самостоятельно (или откатывать самостоятельно) должно быть отдельной фиксацией. Это сохранит Вас тонны головных болей, когда это прибудет время, чтобы сделать слияния или откатывать поврежденные функции.

15
задан Henk Holterman 11 September 2009 в 12:48
поделиться

5 ответов

Хорошо, вот настоящий ответ.

...

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.
  }
}

   ...

Он сочетает в себе две самые интересные части использования C #. Во-первых, чтобы вызвать метод асинхронно, используйте делегат, который имеет магию fancy-pants BeginInvoke .

Затем используйте монитор, чтобы отправить сообщение из LongRunningMethod обратно в ImpatientMethod , чтобы дать ему знать, когда это будет сделано, или, если он не получил от него известий в течение определенного времени, просто откажитесь от него.

(ps - Шучу насчет того, что это был реальный ответ. Я знаю, что есть 2 ^ 9303 способа снять шкуру с кошки. Особенно в .Net)

12
ответ дан 1 December 2019 в 02:37
поделиться

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.

7
ответ дан 1 December 2019 в 02:37
поделиться

You can run the method in a separate thread, and monitor it and force it to exit if it works too long. A good way, if you can call it as such, would be to develop an attribute for the method in Post Sharp so the watching code isn't littering your application.

I've written the following as sample code(note the sample code part, it works, but could suffer issues from multithreading, or if the method in question captures the ThreadAbortException would break it):

static void ActualMethodWrapper(Action method, Action callBackMethod)
{
    try
    {
        method.Invoke();
    } catch (ThreadAbortException)
    {
        Console.WriteLine("Method aborted early");
    } finally
    {
        callBackMethod.Invoke();
    }
}

static void CallTimedOutMethod(Action method, Action callBackMethod, int milliseconds)
{
    new Thread(new ThreadStart(() =>
    {
        Thread actionThread = new Thread(new ThreadStart(() =>
        {
            ActualMethodWrapper(method, callBackMethod);
        }));

        actionThread.Start();
        Thread.Sleep(milliseconds);
        if (actionThread.IsAlive) actionThread.Abort();
    })).Start();
}

With the following invocation:

CallTimedOutMethod(() =>
{
    Console.WriteLine("In method");
    Thread.Sleep(2000);
    Console.WriteLine("Method done");
}, () =>
{
    Console.WriteLine("In CallBackMethod");
}, 1000);

I need to work on my code readability.

2
ответ дан 1 December 2019 в 02:37
поделиться

Methods don't have timeouts in C#, unless your in the debugger or the OS believes your app has 'hung'. Even then processing still continues and as long as you don't kill the application a response is returned and the app continues to work.

Calls to databases can have timeouts.

0
ответ дан 1 December 2019 в 02:37
поделиться

Could you create an Asynchronous Method so that you can continue doing other stuff whilst the "busy" method completes?

0
ответ дан 1 December 2019 в 02:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: