Перейти к содержимому

Как сделать задержку в с

  • автор:

Как в C# добавить задержку при выполнении цикла?

С тех пор, как изобрели TAP await Task.Delay() рулит, а этот ответ превратился во вредный совет. Но вопрос был задан в 2012 году.

22 ноя 2019 в 13:18

Отлично подошёл метод асинхронный:

await Task.Delay() 

Отслеживать
51.6k 201 201 золотой знак 63 63 серебряных знака 245 245 бронзовых знаков
ответ дан 12 ноя 2019 в 8:20
Pavel Shevchuk Pavel Shevchuk
21 1 1 бронзовый знак

Вообще если в Unity вовремя цикла сделать задержку надо, есть хороший вариант с Coroutine:

bool isBusy = false; public GameObject[] players = new GameObject[4]; private void Update() < if (!isBusy) < StartCoroutine(Wait()); >> IEnumerator Wait() < isBusy = true; foreach (GameObject player in players) < Debug.log("player mt24">
)" data-controller="se-share-sheet" data-se-share-sheet-title="Поделиться ссылкой на ответ" data-se-share-sheet-subtitle="" data-se-share-sheet-post-type="answer" data-se-share-sheet-social="facebook twitter " data-se-share-sheet-location="2" data-se-share-sheet-license-url="https%3a%2f%2fcreativecommons.org%2flicenses%2fby-sa%2f4.0%2f" data-se-share-sheet-license-name="CC BY-SA 4.0" data-s-popover-placement="bottom-start">Поделиться
)" title="">Улучшить ответ
ответ дан 22 ноя 2019 в 9:53
2
    Тут хоть слово есть о Unity?
    – And
    18 апр 2020 в 3:24
    @And в Unity на С# пишут
    – Ivan Triumphov
    29 мая 2020 в 3:44
Добавить комментарий|
-2

Я так делаю (по сути это тоже самое что сделал Alex Kapustin только вызов слегка иной ) :

// подключ. библиотеки using System; using System.Threading; . Thread.Sleep(1000); // засыпаем на одну секунду

Task. Delay Метод

Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

Создает задачу, которая будет выполнена после некоторой временной задержки.

Перегрузки

Создает отменяемую задачу, которая завершается через заданное время.

Создает отменяемую задачу, которая завершается через заданное время.

Создает задачу, которая завершается через заданное время.

Создает задачу, которая завершается через заданное время.

Создает задачу, которая завершается через заданное количество миллисекунд.

Создает отменяемую задачу, которая завершается через заданное количество миллисекунд.

Delay(TimeSpan, TimeProvider, CancellationToken)

Создает отменяемую задачу, которая завершается через заданное время.

public: static System::Threading::Tasks::Task ^ Delay(TimeSpan delay, TimeProvider ^ timeProvider, System::Threading::CancellationToken cancellationToken);
public static System.Threading.Tasks.Task Delay (TimeSpan delay, TimeProvider timeProvider, System.Threading.CancellationToken cancellationToken);
static member Delay : TimeSpan * TimeProvider * System.Threading.CancellationToken -> System.Threading.Tasks.Task
Public Shared Function Delay (delay As TimeSpan, timeProvider As TimeProvider, cancellationToken As CancellationToken) As Task
Параметры

Объект TimeSpan для ожидания перед выполнением возвращаемой задачи или InfiniteTimeSpan для неограниченного ожидания.

timeProvider TimeProvider

Объект TimeProvider , с помощью которого интерпретируется delay .

cancellationToken CancellationToken

Токен отмены, который нужно контролировать во время ожидания выполнения задачи.

Возвращаемое значение

Задача, представляющая временную задержку.

Исключения

delay представляет отрицательный интервал времени, отличный от InfiniteTimeSpan.

delay TotalMilliseconds свойство больше 4294967294.

Аргумент timeProvider имеет значение null .

Маркер отмены был отменен. Это исключение сохраняется в возвращаемой задаче.

Применяется к

Delay(TimeSpan, CancellationToken)

Создает отменяемую задачу, которая завершается через заданное время.

public: static System::Threading::Tasks::Task ^ Delay(TimeSpan delay, System::Threading::CancellationToken cancellationToken);
public static System.Threading.Tasks.Task Delay (TimeSpan delay, System.Threading.CancellationToken cancellationToken);
static member Delay : TimeSpan * System.Threading.CancellationToken -> System.Threading.Tasks.Task
Public Shared Function Delay (delay As TimeSpan, cancellationToken As CancellationToken) As Task
Параметры

Время, в течение которого ожидается завершение возвращаемой задачи, или Timeout.InfiniteTimeSpan для неограниченного времени ожидания.

cancellationToken CancellationToken

Токен отмены, который нужно контролировать во время ожидания выполнения задачи.

Возвращаемое значение

Задача, представляющая временную задержку.

Исключения

delay представляет отрицательный интервал времени, отличный от Timeout.InfiniteTimeSpan .

Свойство delay аргумента TotalMilliseconds больше 4294967294 в .NET 6 и более поздних версий или Int32.MaxValue во всех предыдущих версиях.

Задача была отменена.

Предоставленный объект cancellationToken уже удален.

Примеры

В следующем примере запускается задача, которая включает вызов Delay(TimeSpan, CancellationToken) метода с задержкой в 1,5 секунды. До истечения интервала задержки маркер отменяется. В выходных данных примера показано, что в результате TaskCanceledException возникает исключение , а свойству задач Status присваивается значение Canceled.

using System; using System.Threading; using System.Threading.Tasks; public class Example < public static void Main() < CancellationTokenSource source = new CancellationTokenSource(); var t = Task.Run(async delegate < await Task.Delay(TimeSpan.FromSeconds(1.5), source.Token); return 42; >); source.Cancel(); try < t.Wait(); >catch (AggregateException ae) < foreach (var e in ae.InnerExceptions) Console.WriteLine(": ", e.GetType().Name, e.Message); > Console.Write("Task t Status: ", t.Status); if (t.Status == TaskStatus.RanToCompletion) Console.Write(", Result: ", t.Result); source.Dispose(); > > // The example displays output like the following: // TaskCanceledException: A task was canceled. // Task t Status: Canceled 
open System open System.Threading open System.Threading.Tasks let source = new CancellationTokenSource() let t = Task.Run(fun () -> task < do! Task.Delay(TimeSpan.FromSeconds(1.5), source.Token) return 42 >) source.Cancel() try t.Wait() with :? AggregateException as ae -> for e in ae.InnerExceptions do printfn $": " printf $"Task t Status: " if t.Status = TaskStatus.RanToCompletion then printf $", Result: " source.Dispose() // The example displays output like the following: // TaskCanceledException: A task was canceled. // Task t Status: Canceled 
Imports System.Threading Imports System.Threading.Tasks Module Example Public Sub Main() Dim source As New CancellationTokenSource() Dim t = Task.Run(Async Function() Await Task.Delay(TimeSpan.FromSeconds(1.5), source.Token) Return 42 End Function) source.Cancel() Try t.Wait() Catch ae As AggregateException For Each e In ae.InnerExceptions Console.WriteLine(": ", e.GetType().Name, e.Message) Next End Try Console.Write("Task t Status: ", t.Status) If t.Status = TaskStatus.RanToCompletion Then Console.Write(", Result: ", t.Result) End If source.Dispose() End Sub End Module ' The example displays output like the following: ' TaskCanceledException: A task was canceled. ' Task t Status: Canceled 

Обратите внимание, что этот пример включает потенциальное условие гонки: оно зависит от задачи, которая асинхронно выполняет задержку при отмене маркера. Хотя задержка в 1,5 секунды от вызова Delay(TimeSpan, CancellationToken) метода делает это предположение вероятным, тем не менее, возможно, что вызов Delay(TimeSpan, CancellationToken) метода может вернуться до отмены маркера. В этом случае в примере выводятся следующие выходные данные:

Task t Status: RanToCompletion, Result: 42 

Комментарии

Если маркер отмены подается до указанной задержки времени, возникает TaskCanceledException исключение, и задача завершается в Canceled состоянии . В противном случае задача завершается в RanToCompletion состоянии по истечении указанной задержки времени.

Сценарии использования и дополнительные примеры см. в документации по перегрузке Delay(Int32) .

Этот метод зависит от системных часов. Это означает, что задержка времени будет примерно равна разрешению системных часов, если delay аргумент меньше разрешения системных часов, что составляет примерно 15 миллисекундах в системах Windows.

Системные часы, которые используются, являются теми же, что и GetTickCount, на которые не влияют изменения, внесенные в timeBeginPeriod и timeEndPeriod.

Как сделать задержку выполнения кода в Unity C#?

freeExec

не рекомендую делать WaitForSeconds в Update потому что по сути такой код будет начинать каждый тик (Update вызывается 60 вроде бы раз в секунду) новый интервал задержки, и сам Update может встать (или чтото еще в таком духе, надо тестить, вообщем баг явный)

на самом деле такой код может рабоатть, но только для быстрых корутин, не для ожидания 5 сек

IEnumerator Update()

аналогично из Start можно запускать корутину с ожиданием

IEnumerator Start()

лучше запустить корутину из Start() - пример же в доке есть

void Start() < //Start the coroutine we define below named ExampleCoroutine. StartCoroutine(ExampleCoroutine()); >IEnumerator ExampleCoroutine() < //Print the time of when the function is first called. Debug.Log("Started Coroutine at timestamp : " + Time.time); //yield on a new YieldInstruction that waits for 5 seconds. yield return new WaitForSeconds(5); //After we have waited 5 seconds print the time again. Debug.Log("Finished Coroutine at timestamp : " + Time.time); >

Как сделать задержку с интервалом?

Отслеживаю нажатие горячей клавиши пользователем. WndProc - отслеживает сообщения Windows (больше 5 за 1 секунду). Проблема: как избавиться от многочисленного нажатия, чтобы была хотя бы задержка или интервал времени, когда метод SetPrc() будет вызываться ? Иначе получается, что можно очень много раз вызвать метод за 1 секунду. Можно ли как-нибудь заблокировать метод SetPrc() через lock и Thread.Sleep() ?

protected override void WndProc(ref Message keyPressed) < if (keyPressed.Msg == 0x0312) < if (CanWork) < switch (keyPressed.WParam.ToInt32()) < case 1: SetPrtSc(); break; >> > base.WndProc(ref keyPressed); >
  • Вопрос задан более трёх лет назад
  • 188 просмотров

2 комментария

Средний 2 комментария

Константин @nicebmw9 Автор вопроса
Сделал так, но это неправильно. Как через lock оформить ?

using System; using System.ComponentModel; using System.Runtime.InteropServices; using System.Windows.Forms; namespace ScrMaster < public partial class MainForm : Form < private int uniqId = 1; private int ALT = 0x0001; private Keys key = Keys.PrintScreen; private bool canWork = true; Timer timer = new Timer(); public MainForm() < timer.Tick += Timer_Tick; timer.Interval = 5_000; InitializeComponent(); >private void Timer_Tick(object sender, EventArgs e) < canWork = true; timer.Stop(); >private void MainForm_Load(object sender, EventArgs e) < SetHotKey(); this.FormClosing += ClearHotKey; >private void SetHotKey() < RegisterHotKey(this.Handle, uniqId, (uint)ALT, (uint)key); >private void ClearHotKey(object sender, CancelEventArgs e) < UnregisterHotKey(this.Handle, uniqId); >#region Extern Dll [DllImport("user32.dll")] public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); [DllImport("user32.dll")] public static extern bool UnregisterHotKey(IntPtr hWnd, int id); #endregion protected override void WndProc(ref Message keyPressed) < if (keyPressed.Msg == 0x0312) < if (canWork) < switch (keyPressed.WParam.ToInt32()) < case 1: SetPrtSc(); break; >> > base.WndProc(ref keyPressed); > private void SetPrtSc() < canWork = !canWork; MessageBox.Show(""); timer.Start(); >> >

hePPer

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *