我需要做一种“超时”或暂停我的方法10秒(10000毫秒),但我不确定以下是否会起作用,因为我没有多线程。
Thread.Sleep(10000);
我将尝试使用当前的代码,但如果有人能够解释最佳和正确的方法,我将不胜感激,特别是如果上述代码无法正常工作。谢谢!
UPDATE :这个程序实际上是一个控制台应用程序,在该函数中对一个服务器执行许多HTTPWebRequests,所以我希望将它们延迟指定的毫秒数。因此,不需要回调 - 所需要的只是“无条件暂停” - 基本上整个事情停止10秒然后继续。我很高兴C#仍然认为这是一个线程,所以Thread.Sleep(...)会起作用。谢谢大家!
答案 0 :(得分:16)
您可能没有多 - 线程,但您仍在线程中执行:所有代码都在线程中执行。
调用Thread.Sleep
确实会暂停当前线程。你真的希望它无条件地暂停10秒,或者你是否希望能够被其他事情“唤醒”?如果您实际上只使用一个线程,那么调用Sleep
可能是最好的前进方式,但这取决于具体情况。
特别是,如果您正在编写GUI应用程序,则不想要从UI线程中使用Thread.Sleep
,否则您的整个应用程序将在10秒内无响应。
如果您可以提供有关您的申请的更多信息,这将有助于我们更好地为您提供建议。
答案 1 :(得分:3)
这确实会暂停执行的线程/方法10秒。你看到了一个特定的问题吗?
请注意,您不应该Sleep
UI线程 - 而是更好地进行回调。
另请注意,还有其他阻止线程的方法,允许更简单的访问以使其再次运行(如果您在2s后发现它没有问题);例如Monitor.Wait(obj, 10000)
(如果需要唤醒它,允许另一个线程Pulse
):
static void Main() {
object lockObj = new object();
lock (lockObj) {
new Thread(GetInput).Start(lockObj);
Monitor.Wait(lockObj, 10000);
}
Console.WriteLine("Main exiting");
}
static void GetInput(object state) {
Console.WriteLine("press return...");
string s = Console.ReadLine();
lock (state) {
Monitor.Pulse(state);
}
Console.WriteLine("GetInput exiting");
}
您也可以使用Thread.Interrupt
执行此操作,但IMO更麻烦。
答案 2 :(得分:3)
您可以使用单独的线程来执行此操作:
ThreadPool.QueueUserWorkItem(
delegate(object state)
{
Thread.Sleep(1000);
Console.WriteLine("done");
});
但是,如果这是一个Windows窗体应用程序,则需要在Gui线程延迟之后调用代码(本文,例如:How to update the GUI from another thread in C#?)。
[编辑] 刚刚看到您的更新。如果它是一个控制台应用程序,那么这将工作。但是如果你到目前为止还没有使用多个线程,那么你需要知道这个代码将在不同的线程中执行,这意味着你将不得不关注线程同步问题。
如果您不需要背景工作者,请坚持“保持简单”。
答案 3 :(得分:3)
这是一个暂停类,它将暂停所需的毫秒数,并且不会消耗你的CPU资源。
public class PauseClass
{
//(C) Michael Roberg
//Please feel free to distribute this class but include my credentials.
System.Timers.Timer pauseTimer = null;
public void BreakPause()
{
if (pauseTimer != null)
{
pauseTimer.Stop();
pauseTimer.Enabled = false;
}
}
public bool Pause(int miliseconds)
{
ThreadPriority CurrentPriority = Thread.CurrentThread.Priority;
if (miliseconds > 0)
{
Thread.CurrentThread.Priority = ThreadPriority.Lowest;
pauseTimer = new System.Timers.Timer();
pauseTimer.Elapsed += new ElapsedEventHandler(pauseTimer_Elapsed);
pauseTimer.Interval = miliseconds;
pauseTimer.Enabled = true;
while (pauseTimer.Enabled)
{
Thread.Sleep(10);
Application.DoEvents();
//pausThread.Sleep(1);
}
pauseTimer.Elapsed -= new ElapsedEventHandler(pauseTimer_Elapsed);
}
Thread.CurrentThread.Priority = CurrentPriority;
return true;
}
private void pauseTimer_Elapsed(object sender, ElapsedEventArgs e)
{
pauseTimer.Enabled = false;
}
}
答案 4 :(得分:2)
Thread.Sleep很好,而AFAIK是正确的方法。即使你不是多线程的:总有至少一个线程,如果你把它发送到睡眠状态,它就会睡觉。
另一种(错误的)方式is a spinlock,类似于:
// Do never ever use this
private void DoNothing(){ }
private void KillCPU()
{
DateTime target = DateTime.Now.AddSeconds(10);
while(DateTime.Now < target) DoNothing();
DoStuffAfterWaiting10Seconds();
}
令人遗憾的是,这仍然被人们使用,虽然它将暂停你的程序10秒,但它将以100%CPU利用率运行(好吧,在多核系统上它是一个核心)。
答案 5 :(得分:1)
是的,这很好用。
您不必使用多个线程来使用Thread类中的某些方法。你总是至少有一个线程。
答案 6 :(得分:0)
对于超时,您应该有一个静态volatile boolean isRunning类字段。当新线程启动时,isRunning必须变为true,并且最后必须变为false。
主线程应该有一个方法,在您定义的超时期间为isRunning循环。超时结束时,您应该实现逻辑。但是,永远不要使用中止线程方法。
暂停......没有一个简单的解决方案。这取决于你在线程内做了什么。但是,您可以查看Monitor.Wait。
答案 7 :(得分:-2)
如果可以使用异步方法,则可以执行一些操作,例如在某个位置暂停该功能。暂停设置为false后,它将继续执行方法中的其余代码。由于这是一种异步方法,并且延迟是异步的,因此UI执行不会受到影响。 *请注意,只有.net 4.5及更高版本支持asyn。
bool pause = true;
void async foo()
{
//some code
while (pause)
{
await Task.Delay(100);
}
//some code
}