暂停set of milliseconds的方法

时间:2009-07-01 09:32:15

标签: c# multithreading timeout

我需要做一种“超时”或暂停我的方法10秒(10000毫秒),但我不确定以下是否会起作用,因为我没有多线程。

Thread.Sleep(10000);

我将尝试使用当前的代码,但如果有人能够解释最佳和正确的方法,我将不胜感激,特别是如果上述代码无法正常工作。谢谢!

UPDATE :这个程序实际上是一个控制台应用程序,在该函数中对一个服务器执行许多HTTPWebRequests,所以我希望将它们延迟指定的毫秒数。因此,不需要回调 - 所需要的只是“无条件暂停” - 基本上整个事情停止10秒然后继续。我很高兴C#仍然认为这是一个线程,所以Thread.Sleep(...)会起作用。谢谢大家!

8 个答案:

答案 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
        }