Приостановка метода для набора # миллисекунд

Все сказанное и сделанное здесь для этого код O'caml. Алгоритм очевиден из кода ..

let combi n lst =
    let rec comb l c =
        if( List.length c = n) then [c] else
        match l with
        [] -> []
        | (h::t) -> (combi t (h::c))@(combi t c)
    in
        combi lst []
;;
16
задан Maxim Zaslavsky 1 July 2009 в 09:44
поделиться

6 ответов

У вас может не быть многопоточности , но вы по-прежнему выполняете в потоке: весь код выполняется в потоке.

Вызов Thread. Сон действительно приостановит текущий поток. Вы действительно хотите, чтобы он безоговорочно останавливался на 10 секунд, или вы хотите, чтобы вас «разбудило» что-то еще? Если вы на самом деле используете только один поток, вызов Sleep вполне может быть лучшим выходом, но это будет зависеть от ситуации.

В частности, если вы пишете приложение с графическим интерфейсом, вы , не хочет использовать Thread.Sleep из потока пользовательского интерфейса, иначе все ваше приложение перестанет отвечать на запросы в течение 10 секунд.

Если бы вы могли предоставить дополнительную информацию о своем приложении, это поможет нам дать вам лучший совет.

17
ответ дан 30 November 2019 в 08:04
поделиться

Это действительно приостановит выполнение поток / метод на 10 секунд. Вы видите конкретную проблему?

Обратите внимание, что вам не следует Спать поток пользовательского интерфейса - вместо этого лучше выполнить обратный вызов.

Обратите также внимание на то, что существуют другие способы блокировки потока, которые позволяют упростить доступ для его возобновления (если вы обнаружите, что это нормально после 2 секунд); например Monitor.Wait (obj, 10000) (позволяя другому потоку использовать Pulse , если необходимо, чтобы разбудить его):

static void Main() {
    object lockObj = new object();
    lock (lockObj) {
        new Thread(GetInput).Start(lockObj);
        Monitor.Wait(lockObj, 10000);
    }
    Console.WriteLine("Main exiting");
}
static void GetInput(object state) {
    Console.WriteLine("press return...");
    string s = Console.ReadLine();
    lock (state) {
        Monitor.Pulse(state);
    }
    Console.WriteLine("GetInput exiting");
}

Вы можете сделать это с помощью Thread.Interrupt тоже, но ИМО более беспорядочный.

3
ответ дан 30 November 2019 в 08:04
поделиться

Вы можете использовать отдельный поток для этого:

   ThreadPool.QueueUserWorkItem(
       delegate(object state)
       {
           Thread.Sleep(1000);
           Console.WriteLine("done");
       });

Но если это это приложение Windows Forms, вам нужно будет вызвать код после задержки из потока Gui (эта статья, например: Как обновить графический интерфейс из другого потока на C #? ).

[Edit] Только что увидел ваше обновление. Если это консольное приложение, то это сработает. Но если вы до сих пор не использовали несколько потоков, вам нужно знать, что этот код будет выполняться в другом потоке, а это значит, что вам придется позаботиться о проблемах синхронизации потоков.

Если вам не нужны второстепенные работники, придерживайтесь «простоты».

3
ответ дан 30 November 2019 в 08:04
поделиться

Thread.Sleep в порядке, и AFAIK правильным образом. Даже если вы не являетесь многопоточным: всегда есть хотя бы один поток, и если вы отправите его в спящий режим, он спит.

Другой ( плохой ) способ - спин-блокировка , что-то вроде:

// Do never ever use this
private void DoNothing(){ }

private void KillCPU()
{
    DateTime target = DateTime.Now.AddSeconds(10);
    while(DateTime.Now < target) DoNothing();
    DoStuffAfterWaiting10Seconds();
}

Это, к сожалению, все еще используется людьми, и хотя он остановит вашу программу на 10 секунд, он будет работать со 100% загрузкой ЦП (ну, в многоядерных системах это одно ядро).

3
ответ дан 30 November 2019 в 08:04
поделиться

Да, это прекрасно работает.

Вам не нужно иметь несколько потоков, чтобы использовать некоторых методов класса Thread. У вас всегда есть хотя бы одна ветка.

1
ответ дан 30 November 2019 в 08:04
поделиться

Для тайм-аута у вас должно быть статическое изменчивое логическое поле класса isRunning. Когда запускается новый поток, isRunning должно стать истинным, а в конце - ложным.

У основного потока должен быть метод, который выполняет цикл для isRunning в течение заданного вами тайм-аута. Когда истечет время ожидания, вы должны реализовать логику. Но никогда не используйте метод прерывания потока.

Пауза ... простого решения не существует. Это зависит от того, что вы делаете внутри потока. Однако вы можете посмотреть Monitor.Wait .

0
ответ дан 30 November 2019 в 08:04
поделиться
Другие вопросы по тегам:

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