Подтвердить что ты не робот

Как я могу выполнить короткую задержку на С# без использования сна?

Я невероятно новичок в программировании, и я до сих пор учился достаточно хорошо, но я все еще не могу понять, как сделать задержку так, как я хочу. То, над чем я работаю, - это своего рода тестовая "игра", использующая приложение форм Windows, которое включает в себя боевую систему. В нем я хочу сделать NPC, который выполняет действие каждые пару секунд. Проблема в том, что я также хочу позволить игроку взаимодействовать между атаками. Thread.sleep действительно не работает для меня не только потому, что я не знаю, как многопоточно, но всякий раз, когда я пытаюсь запустить его, скажем, вот так:

 textBox1.Text += "\r\nThread Sleeps!";
 System.Threading.Thread.Sleep(4000);
 textBox1.Text += "\r\nThread awakens!";

Кажется, он настаивает на том, чтобы спать первым, а затем печатать обе строки.

Я думаю, что все, что я могу сказать в данный момент, но если это еще слишком расплывчато или многословно, не стесняйтесь говорить мне.

Короче говоря, In С# я хочу сделать что-то задержка перед запуском, но в то же время разрешить взаимодействие с пользователем.

4b9b3361

Ответ 1

Если вы используете .NET 4.5, вы можете использовать новую структуру async/await для сна, не блокируя поток.

Как это работает, вы отмечаете функцию, которая нуждается в асинхронных операциях, с ключевым словом async. Это всего лишь намек на компилятор. Затем вы используете ключевое слово await в строке, где вы хотите, чтобы ваш код выполнялся асинхронно, и ваша программа будет ждать, не блокируя нить или пользовательский интерфейс. Метод, который вы вызываете (в строке ожидания), должен быть помечен также ключевым словом async и обычно называется именем, заканчивающимся на Async, как в ImportFilesAsync.

Что вам нужно сделать в вашем примере:

  • Убедитесь, что ваша программа имеет .Net Framework 4.5 как Target Framework
  • Отметьте свою функцию, которая должна спать с ключевым словом async (см. пример ниже)
  • Добавьте using System.Threading.Tasks; в свой код.

Теперь ваш код готов использовать метод Task.Delay вместо метода System.Threading.Thread.Sleep (можно использовать await на Task.Delay, потому что Task.Delay помечен async в его определении).

    private async void button1_Click(object sender, EventArgs e)
    {
      textBox1.Text += "\r\nThread Sleeps!";
      await Task.Delay(3000);
      textBox1.Text += "\r\nThread awakens!";
    }

Здесь вы можете узнать больше о Task.Delay и Await.

Ответ 2

Извините за пробуждение старого вопроса вроде этого. Но я думаю, что первоначальный автор хотел в качестве ответа:

Вам нужно заставить свою программу сделать графическое обновление после внесения изменений в текстовое поле1. Вы можете сделать это, вызвав Update();

textBox1.Text += "\r\nThread Sleeps!";
textBox1.Update();
System.Threading.Thread.Sleep(4000);
textBox1.Text += "\r\nThread awakens!";
textBox1.Update();

Обычно это будет выполняться автоматически, когда поток будет выполнен. Ex, вы нажимаете кнопку, изменения вносятся в текст, нити умирают, а затем .Update() запускается, и вы видите изменения. (Я не эксперт, поэтому я не могу сказать вам, когда его уволили, но что-то подобное в любом случае.)

В этом случае вы делаете изменения, приостанавливаете поток, а затем снова меняете текст, и когда поток наконец умирает, загорается .Update(). Это приводит к тому, что вы видите только последнее изменение, внесенное в текст.

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

Ответ 3

Возможно, вы можете использовать таймеры: http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx

Таймеры могут обеспечить точность до 1 миллисекунды. В зависимости от интервала тика будет генерироваться событие. Сделайте свой материал внутри события тика.

Ответ 4

private void WaitNSeconds(int seconds)
{
    if (seconds < 1) return;
    DateTime _desired = DateTime.Now.AddSeconds(seconds);
    while (DateTime.Now < _desired) {
         Thread.Sleep(1);
         System.Windows.Forms.Application.DoEvents();
    }
}

Ответ 5

Добавив using System.Timers; в свою программу, вы можете использовать эту функцию:

private static void delay(int Time_delay)
{
   int i=0;
  //  ameTir = new System.Timers.Timer();
    _delayTimer = new System.Timers.Timer();
    _delayTimer.Interval = Time_delay;
    _delayTimer.AutoReset = false; //so that it only calls the method once
    _delayTimer.Elapsed += (s, args) => i = 1;
    _delayTimer.Start();
    while (i == 0) { };
}

Задержка - это функция и может использоваться как:

delay(5000);