Thread.Sleep(5000) を使用できることはわかっていますが、スレッドがブロックされます。呼び出しを 5 秒間遅らせたいのですが、スレッドをブロックしたくありません。
4 に答える
これに使えますSystem.Windows.Forms.Timer
。間隔を 5000 ミリ秒、つまり 5 秒に設定し、経過イベントをフードしてコードを記述します。
タイマーの詳細については、これをお読みください
1 つの可能性は、それをスレッドプールにフォークすることです。
ThreadPool.QueueUserWorkItem(o => { Thread.Sleep(5000); DoSomething(); });
Task.Factory を使用して新しいスレッドを生成できます。Thread.Sleep を呼び出しても、メイン スレッドはブロックされません。これがベストプラクティスだと言っているわけではありませんが、あなたは簡単な方法を要求しました。そして、これは私がすぐに思いつくことができる最も単純なものです。
class Program
{
static void Main(string[] args)
{
Task.Factory.StartNew(() =>
{
// wait for 5 seconds or user hit Enter key cancel the task
Thread.Sleep(5000);
DoStuff();
});
Console.WriteLine("Here's the main thread.");
Console.Read();
}
private static void DoStuff()
{
Console.WriteLine("Task done!");
}
}
これは出力されます:
Here's the main thread. Task done!
.NET 4.5 では、これはさらに簡単になります。
class Program
{
static void Main(string[] args)
{
DoStuff(5000);
Console.WriteLine("Here's the main thread.");
Console.Read();
}
private static async void DoStuff(int delay = 0)
{
await Task.Delay(delay);
Console.WriteLine("Task done!");
}
}
出力は同じになります。
Here's the main thread. Task done!
async
を使用する場合は、メソッドをマークする必要があることに注意してawait
ください。
.NET 4.5
UI フレームワークのコンテキストでは、特殊なスレッド コンテキストがあります。UI を操作するには、UI を所有するスレッドでコードを実行する必要があります。そうしないと、未処理の例外が発生します。したがって、非同期タスクがイベント ハンドラーから返されると、UI フレームワークは完了イベントを内部キューにスケジュールします。ある時点で、完了が発生し、UI スレッドが前述の制限の完了を処理します。UI コンテキストの場合、以下を使用できます。
async void MyButton_Click(object sender, System.EventArgs e) {
await Task.Delay(5000); // UI thread context for the win
DoYourCall();
}
その特殊なスレッド化コンテキストが存在しない他の特定の状況では、await を実行すると、呼び出し元のスレッドが中断され、単語が示すように実際に await が実行されます。状態はまだメモリ内にありますが、スレッドはスレッド プールを切り離してスケジュールし、完了時にプールからスレッドを提供します (したがって、既定の動作)。以下を使用します。
Task.Run(async () => {
await Task.Delay(5000);
DoYourCall();
});
.NET 4.0
Task.Factory.StartNew(() => {
Thread.Sleep(5000);
DoYourCall();
});