Как прервать длительный метод?

У меня есть длительный метод, и я хочу добавить в него тайм-аут. Возможно ли это сделать? Что-то вроде:

AbortWaitSeconds(20)
{
    this.LongRunningMethod();
}

Где, когда он достиг 20 секунд, метод будет прерван. У метода нет цикла, и у меня нет элемента управления / кода над этим методом.

 Eugene Ryabtsev31 мая 2012 г., 07:33
Вы имеете в виду процесс ОС, например, внешнее приложение или просто какой-то длинный расчет внутри вашего приложения, в том же или другом потоке?
 John Isaiah Carmona31 мая 2012 г., 07:34
@EugeneRyabtsev Длинный расчет внутри моего приложения в той же теме.

Ответы на вопрос(5)

Выполните вычисления в фоновом потоке и дождитесь окончания потока. Чтобы прервать расчет, используйтеThread.Abort()ДадимThreadAbortException в теме расчета.

Поскольку у вас нет контроля над этим кодом, я считаю, что правильным подходом было бы запустить этот код, используя WaitHandles и ThreadPool:

WaitHandle waitHandle = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem(new WaitCallback(<long running task delegate>), waitHandle);
WaitHandle.WaitAll(new[]{ waitHandle }, <timeout>);

Вот Вы можете найти больше информации о том, как работает WaitHandle.

 31 мая 2012 г., 08:06
Правильный. Извини за это. Затем Thread.Join (& lt; timeout & gt;) плюс Abort, как показано в других ответах, должны сделать свое дело.Here Есть другие действительные решения этой же проблемы.
 31 мая 2012 г., 07:55
Это не прекращает «длительный процесс».

попробуй это

class Program
{
    static void Main(string[] args)
    {
        if (RunWithTimeout(LongRunningOperation, TimeSpan.FromMilliseconds(3000)))
        {
            Console.WriteLine("Worker thread finished.");
        }
        else
        {
            Console.WriteLine("Worker thread was aborted.");
        }
    }

    static bool RunWithTimeout(ThreadStart threadStart, TimeSpan timeout)
    {
        Thread workerThread = new Thread(threadStart);

        workerThread.Start();

        bool finished = workerThread.Join(timeout);
        if (!finished)
            workerThread.Abort();

        return finished;
    }

    static void LongRunningOperation()
    {
        Thread.Sleep(5000);
    }
}

ты можешь видетьЭто

 31 мая 2012 г., 07:52
@zespri не блокирует навсегда сокеты, не устанавливает таймауты сокетов или не использует опрос сокетов с таймаутами, все в цикле.
 31 мая 2012 г., 07:54
@ Евгений Рябцев просто кое-что для ОП рассмотрит
 31 мая 2012 г., 07:50
Следует отметить одну вещь: если поток заблокирован (в состоянии ожидания) (например, ожидает в сокете), он не будет прерван, пока не разблокируется. И у нас нет контроля, когда он разблокируется.
 31 мая 2012 г., 07:51
Кажется, это правильно. Хотя это может быть возможно сделать в основной теме, в соответствии с вопросом. Как и с запуском таймера, выполнением Thread.Abort () OnTimer и перехватом этого ThreadAbortException, которое кажется каким-то неправильным.
Решение Вопроса

Увидетьмой ответ на этот вопрос для общего решения.

 John Isaiah Carmona31 мая 2012 г., 08:59
Что этоwhile (t.ThreadState != ThreadState.Running) линию делать?
 John Isaiah Carmona31 мая 2012 г., 09:34
Спасибо, я использую ваш код, но вместоAutoResetEvent, Я используюThread.Join, Не знаю, есть ли разница. В очередной раз благодарим за помощь. :)
 John Isaiah Carmona31 мая 2012 г., 07:57
Wouldn & APOS; тThread.Join сделать трюк?
 31 мая 2012 г., 07:59
@JohnIsaiahCarmona: Возможно, но я мало что знаю о многопоточности; p Могут быть тонкие различия. Читая об этом сейчас.
 31 мая 2012 г., 09:24
@JohnIsaiahCarmona: Это просто гарантирует, что поток действительно запустился перед началом «обратного отсчета». Скажем, запуск потока занимает 20 мс, а ограничение времени ожидания - 10 мс, поток даже не запустился бы. Для более длительных таймаутов это не нужно.

Вы можете прервать длительно работающий процесс из одного и того же потока, если у вас есть кодовая точка для введения проверки и выхода. Это связано с тем, что поток явно занят, поэтому он не может обрабатывать проверки, чтобы прервать сам себя. Итак, ваш пример, который содержит только один вызов «LongRunningMethod»; не может быть прервана из той же темы. Вам нужно показать больше кода, чтобы получить указание по этому вопросу.

Как правило, долгосрочные задачи лучше всего отправлять в разные потоки (например, через BackgroundWorker или новый поток), чтобы ониcan быть прерванным

Вот простой способ сделать это;

private void StartThread()
{
    Thread t = new Thread(LongRunningMethod);
    t.Start();
    if (!t.Join(10000)) // give the operation 10s to complete
    {
        // the thread did not complete on its own, so we will abort it now
        t.Abort();
    }
}

private void LongRunningMethod()
{
    // do something that'll take awhile
}
 31 мая 2012 г., 08:20
Нет, он просто дает потоку 10 секунд для завершения, начиная с момента, когда вы вызываете .Join - если поток уже завершен, задержки не будет.
 John Isaiah Carmona31 мая 2012 г., 08:12
если у меня есть другая строка кода после вызоваStartThread() метод, он будет ждать 10 секунд, чтобы запустить его?

Ваш ответ на вопрос