web-dev-qa-db-ja.com

スリープを使用せずにC#で短い遅延を実行するにはどうすればよいですか?

私はプログラミングには信じられないほど新しく、今まで十分に学んできたと思いますが、それでも私が望むように遅延を作るという考えを理解することはできません。私が取り組んでいるのは、戦闘システムを含むWindowsフォームアプリケーションを使用した、一種のテスト「ゲーム」です。その中で、数秒ごとにアクションを実行するNPCを作成したいと思います。問題は、プレイヤーが攻撃間でやり取りできるようにすることです。 Thread.sleepは、マルチスレッドの方法がわからないだけでなく、実行しようとするたびに次のように動作するように思えます。

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

最初にスリープし、次に両方の行を印刷することを主張するようです。

現時点ではそれだけでいいと思いますが、それでもまだ曖昧すぎるか、言葉が長すぎる場合は、お気軽に教えてください。

要するに、C#では、実行する前に何かを遅らせたいが、同時にユーザーとの対話を許可したい。

27
user2706003

.NET 4.5を使用している場合は、新しいasync/awaitフレームワークを使用して、スレッドをロックせずにスリープできます。

仕組みは、asyncキーワードを使用して、非同期操作が必要な関数をマークすることです。これはコンパイラーへの単なるヒントです。次に、コードを非同期に実行する行でawaitキーワードを使用すると、プログラムはスレッドまたはUIをロックせずに待機します。 (await行で)呼び出すメソッドもasyncキーワードでマークする必要があり、通常はImportFilesAsyncのようにAsyncで終わる名前が付けられます。

あなたの例で行う必要があるのは:

  1. プログラムに。Net Framework 4.5Target Frameworkとしてあることを確認してください
  2. asyncキーワードを使用して、スリープする必要がある関数をマークします(以下の例を参照)
  3. using System.Threading.Tasks;をコードに追加します。

これで、コードはTask.Delayメソッドの代わりにSystem.Threading.Thread.Sleepメソッドを使用する準備ができました(定義でTask.Delayawaitでマークされているため、Task.Delayasyncを使用できます) 。

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 について詳しく読むことができます。

58
Ohlin

このような古い質問を目覚めさせてすみません。しかし、元の著者が答えとして欲しかったものは次のとおりだったと思います。

Textbox1に変更を加えた後、プログラムでグラフィックの更新を強制する必要があります。あなたはUpdate();を呼び出すことでそれを行うことができます

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

通常、これはスレッドが完了すると自動的に行われます。たとえば、ボタンを押すと、テキストに変更が加えられ、スレッドが終了し、.Update()が実行されて変更が表示されます。 (私は専門家ではありませんので、いつ解雇されたかはわかりませんが、これは何らかの形で似ています。)

この場合、変更を行い、スレッドを一時停止してからテキストを再度変更し、スレッドが最終的に終了すると、.Update()が起動されます。これにより、テキストに加えられた最後の変更のみが表示されます。

テキストの変更の間に長い実行があった場合、同じ問題が発生します。

4
Tomas Frid

プログラムに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);
2
user8413784

おそらくタイマーを使用できます: http://msdn.Microsoft.com/en-us/library/system.timers.timer.aspx

タイマーは、最大1ミリ秒の精度を提供できます。ティック間隔に応じて、イベントが生成されます。 tickイベント内で何かを行います。

1
Abhishek Shetty
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();
    }
}
0
Khalid