0

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

4

4 回答 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 回答