是否有一种简单的方法可以在不阻塞调用程序线程的情况下延迟约5秒的调用?

时间:2013-08-25 08:34:01

标签: c#

我知道我可以使用Thread.Sleep(5000),但它会阻塞线程。我想将呼叫延迟5秒,但不阻止线程。

4 个答案:

答案 0 :(得分:2)

您可以使用System.Windows.Forms.Timer。将其间隔设置为5000毫秒,即5秒,并将其经过的事件限制为编写代码。

有关定时器的更多信息,请阅读this

答案 1 :(得分:1)

一种可能性是将其分配到threadpool

 ThreadPool.QueueUserWorkItem(o => { Thread.Sleep(5000); DoSomething(); });

答案 2 :(得分: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

答案 3 :(得分:-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();
}

在不存在该专用线程上下文的任何其他给定情况下,执行await将暂停调用线程以实际执行await,如同单词建议的那样。状态仍在内存中,但线程会分离并调度线程池,以便在完成时从池中提供线程(因此,默认行为)。使用以下内容。

Task.Run(async () => {
  await Task.Delay(5000);
  DoYourCall();
});

.NET 4.0

Task.Factory.StartNew(() => {
  Thread.Sleep(5000);
  DoYourCall();
});