我知道我可以使用 Thread.Sleep(5000),但它会阻塞线程。我想将调用延迟 5 秒,但不阻塞线程。
问问题
390 次
4 回答
2
你可以用System.Windows.Forms.Timer
这个。将其间隔设置为 5000 毫秒,即 5 秒,并隐藏其经过的事件以编写您的代码。
有关计时器的更多信息,请阅读此
于 2013-08-25T08:35:16.977 回答
1
一种可能性是将其分叉到线程池:
ThreadPool.QueueUserWorkItem(o => { Thread.Sleep(5000); DoSomething(); });
于 2013-08-25T08:36:28.597 回答
0
您可以使用 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
。
于 2013-08-25T08:44:18.460 回答
-3
.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();
}
在不存在该专门线程上下文的任何其他给定情况下,执行等待将挂起调用线程以实际执行等待,正如单词所暗示的那样。状态仍在内存中,但线程分离并调度线程池以在完成发生时从池中提供一个线程(因此,默认行为)。使用以下内容。
Task.Run(async () => {
await Task.Delay(5000);
DoYourCall();
});
.NET 4.0
Task.Factory.StartNew(() => {
Thread.Sleep(5000);
DoYourCall();
});
于 2013-08-25T08:41:11.480 回答