Как ограничить время выполнения функции в Си-Шарп?
У меня проблема. Я пишу тест, и у меня есть функция, которая выполняется за 2 секунды или через ~5 минут(в зависимости от входных данных). И я хотел бы, чтобы остановить эту функцию, если она выполняется более 3 секунд...
Как я могу это сделать?
Спасибо большое!
7 ответов
лучшим способом было бы то, что ваша функция может проверять свое время выполнения достаточно часто, чтобы решить остановить его.
Если это не так, запустите функцию в отдельном потоке. В главном потоке запустите таймер на 3 секунды. Когда таймер истекает, убейте отдельный поток, используя нить.Abort () (конечно, если функция уже не закончена). Увидеть пример кода и preacuations использования в функции "документы".
хорошо..., У меня был тот же вопрос, и после прочтения всех ответов здесь и упомянутых блогов, я остановился на этом,
Это позволяет мне выполнить любой блок кода с ограничением по времени, объявите метод обертки
public static bool ExecuteWithTimeLimit(TimeSpan timeSpan, Action codeBlock)
{
try
{
Task task = Task.Factory.StartNew(() => codeBlock());
task.Wait(timeSpan);
return task.IsCompleted;
}
catch (AggregateException ae)
{
throw ae.InnerExceptions[0];
}
}
и используйте это, чтобы обернуть любой блок кода, как это
// code here
bool Completed = ExecuteWithTimeLimit(TimeSpan.FromMilliseconds(1000), () =>
{
//
// Write your time bounded code here
//
});
//More code
вы можете использовать шаблон fork/join, в параллельной библиотеке задач это реализовано с помощью задач.WaitAll()
using System.Threading.Tasks;
void CutoffAfterThreeSeconds() {
// start function on seperate thread
CancellationTokenSource cts = new CancellationTokenSource();
Task loop = Task.Factory.StartNew(() => Loop(cts.Token));
// wait for max 3 seconds
if(Task.WaitAll(new Task[]{loop}, 3000)){
// Loop finished withion 3 seconds
} else {
// it did not finish within 3 seconds
cts.Cancel();
}
}
// this one takes forever
void Loop() {
while (!ct.IsCancellationRequested) {
// your loop goes here
}
Console.WriteLine("Got Cancelled");
}
это запустит другую задачу в отдельном потоке, а затем дождется 3000 миллисекунд для ее завершения. Если он закончил в течение тайм-аута, он возвращает true, else false, поэтому вы можете использовать это, чтобы решить, что делать дальше.
вы можете использовать CancellationToken для связи с другим потоком, что это результат нет нужно больше времени, чтобы он мог остановиться изящно.
С Уважением Герт-Ян
лучший способ в C# остановить функцию посередине-это return
ключевое слово в функции, но как узнать, когда использовать return
ключевое слово, чтобы остановить функцию посередине, после того, как она длится не менее 3 секунд? The Stopwatch
класс System.Diagnostics
ответ. Эта сложная функция, которая длится от 2 секунд до 5 минут (в зависимости от входных данных), логически использует много циклов и, возможно, даже рекурсию, поэтому мое решение для вас заключается в том, что в первой строке кода этой функции создайте пример Stopwatch
используя System.Diagnostics
С new
ключевое слово, запустите его, вызвав Start()
функция класса секундомера, и для каждого цикла и цикла, в начале, добавьте следующий код:
if (stopwatch.ElapsedMilliseconds >= 3000) {
stopwatch.Stop();
// or
stopwatch.Reset();
return;
}
(совет: вы можете ввести его руками один раз, скопировать его Ctrl+C, а затем просто вставить его Ctrl+V). Если эта функция использует рекурсию, чтобы сохранить память, сделайте глобальный экземпляр секундомера, а не сначала создайте его как локальный экземпляр, и запустите его, если это не так запуск в начале кода. Вы можете знать, что с IsRunning
класса секундомер. После этого спросите, прошло ли время более 3 секунд, и если да (true
) остановите или сбросьте секундомер и используйте return
ключевое слово, чтобы остановить цикл рекурсии, очень хороший старт в функции, если ваша функция длится долго из-за рекурсии больше, чем циклов. Что это. Как видите, это очень просто, и я протестировал это решение, и результаты показали, что оно работает! Попробовать его себя!
запустите эту функцию в потоке и убейте ее через 3 секунды или проверьте прошедшее время внутри этой функции (я думаю, что это цикл).
используйте обратные вызовы ОС со счетчиком производительности hi, а затем убейте свой поток, если он существует
Так как C# и .net framework не являются средами реального времени, вы не можете гарантировать даже количество 3 секунд. Даже если вы приблизитесь к этому, Вам все равно придется позвонить
if(timeSpan > TimeSpan.FromSeconds(3) then goto endindentifier;
перед каждый вызов метода.
все это просто неправильно, поэтому нет, просто нет надежного способа сделать это из того, что я знаю.
хотя вы можете попробовать это решение
но я просто не стал бы делать такие вещи в .net-приложении.