将方法暂停指定的毫秒数

发布于 2024-07-26 10:33:06 字数 399 浏览 1 评论 0原文

我需要在我的方法中进行某种“超时”或暂停 10 秒(10000 毫秒),但我不确定以下内容是否有效,因为我没有多线程。

Thread.Sleep(10000);

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

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

I need to do a sort of "timeout" or pause in my method for 10 seconds (10000 milliseconds), but I'm not sure if the following would work as i do not have multi-threading.

Thread.Sleep(10000);

I will try to use that current code, but I would appreciate if someone could explain the best and correct way of doing this, especially if the above code does not work properly. Thanks!

UPDATE: This program is actually a console application that in the function in question is doing many HTTPWebRequests to one server, so I wish to delay them for a specified amount of milliseconds. Thus, no callback is required - all that is needed is an "unconditional pause" - basically just the whole thing stops for 10 seconds and then keeps going. I'm pleased that C# still considers this as a thread, so Thread.Sleep(...) would work. Thanks everybody!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

初见你 2024-08-02 10:33:07

如果您可以有一个异步方法,您可以执行一些操作,例如在某个位置暂停该函数。 一旦暂停设置为 false,它将继续执行方法中的其余代码。 由于这是一个异步方法并且延迟也是异步的,因此 UI 执行不会受到影响。
* 请注意,仅 .net 4.5 及更高版本支持异步。

bool pause = true;

       void async foo()
        {
        //some code

            while (pause)
             {
             await Task.Delay(100);
             }

        //some code
        }

If you can have an async method, you can do something like to pause the function at a certain location. Once pause is set false it will continue executing the rest of the code in the method. Since this is an async method and delay is async too UI execution wouldn't be affected.
* Please note that asyn is supported only in .net 4.5 and higher.

bool pause = true;

       void async foo()
        {
        //some code

            while (pause)
             {
             await Task.Delay(100);
             }

        //some code
        }
始终不够爱げ你 2024-08-02 10:33:06

您可能没有线程,但您仍然在线程中执行:所有代码都在线程中执行。

调用 Thread.Sleep 确实会暂停当前线程。 你真的希望它无条件暂停10秒,还是希望能够被其他发生的事情“唤醒”? 如果您实际上只使用一个线程,那么调用 Sleep 可能是最好的方法,但这取决于具体情况。

特别是,如果您正在编写 GUI 应用程序,您希望在 UI 线程中使用 Thread.Sleep,否则您的整个应用程序将在 10 年内无响应秒。

如果您能提供有关您的申请的更多信息,这将有助于我们为您提供更好的建议。

You may not have multi-threading, but you're still executing within a thread: all code executes in a thread.

Calling Thread.Sleep will indeed pause the current thread. Do you really want it to unconditionally pause for 10 seconds, or do you want to be able to be "woken up" by something else happening? If you're only actually using one thread, calling Sleep may well be the best way forward, but it will depend on the situation.

In particular, if you're writing a GUI app you don't want to use Thread.Sleep from the UI thread, as otherwise your whole app will become unresponsive for 10 seconds.

If you could give more information about your application, that would help us to advise you better.

り繁华旳梦境 2024-08-02 10:33:06

Thread.Sleep 很好,而且据我所知是正确的方法。 即使您不是多线程的:总是至少有一个线程,如果您将其发送到睡眠状态,它就会睡眠。

另一种()方式是自旋锁,类似于

// 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 利用率运行(嗯,在多核系统上它是一个核心)。

Thread.Sleep is fine, and AFAIK the proper way. Even if you are not Multithreaded: There is always at least one Thread, and if you send that to sleep, it sleeps.

Another (bad) way is a spinlock, something like:

// Do never ever use this
private void DoNothing(){ }

private void KillCPU()
{
    DateTime target = DateTime.Now.AddSeconds(10);
    while(DateTime.Now < target) DoNothing();
    DoStuffAfterWaiting10Seconds();
}

This is sadly still being used by people and while it will halt your program for 10 seconds, it will run at 100% CPU Utilization (Well, on Multi-Core systems it's one core).

大姐,你呐 2024-08-02 10:33:06

这确实会使正在执行的线程/方法暂停 10 秒。 您看到具体问题了吗?

请注意,您不应该睡眠 UI 线程 - 最好进行回调。

另请注意,还有其他阻塞线程的方法,可以更简单地访问以使其再次运行(如果您发现 2 秒后正常); 例如 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< 来做到这一点/code> 也是如此,但在我看来,这更混乱。

That will indeed pause the executing thread/method for 10 seconds. Are you seeing a specific problem?

Note that you shouldn't Sleep the UI thread - it would be better to do a callback instead.

Note also that there are other ways of blocking a thread that allow simpler access to get it going again (if you find it is OK after 2s); such as Monitor.Wait(obj, 10000) (allowing another thread to Pulse if needed to wake it up):

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");
}

You can do this with Thread.Interrupt too, but IMO that is messier.

机场等船 2024-08-02 10:33:06

您可以使用单独的线程来执行此操作:

   ThreadPool.QueueUserWorkItem(
       delegate(object state)
       {
           Thread.Sleep(1000);
           Console.WriteLine("done");
       });

但是,如果这是一个 Windows 窗体应用程序,您将需要在延迟后从 Gui 线程调用代码(本文例如:如何从 C# 中的另一个线程更新 GUI?) 。

[编辑]刚刚看到您的更新。 如果它是控制台应用程序,那么这将起作用。 但如果到目前为止您还没有使用过多线程,那么您需要注意此代码将在不同的线程中执行,这意味着您必须注意线程同步问题。

如果您不需要后台工作人员,请坚持“保持简单”。

You could use a separate thread to do it:

   ThreadPool.QueueUserWorkItem(
       delegate(object state)
       {
           Thread.Sleep(1000);
           Console.WriteLine("done");
       });

But, if this is a Windows Forms app, you will need to invoke the code after the delay from the Gui thread (this article, for example: How to update the GUI from another thread in C#?).

[Edit] Just saw your update. If it's a console app, then this will work. But if you haven't used multiple threads so far, then you need to be aware that this code will be executed in a different thread, which means you will have to take care about thread synchronization issues.

If you don't need background workers, stick to "keeping it simple".

記憶穿過時間隧道 2024-08-02 10:33:06

这是一个暂停类,它将暂停所需的毫秒并且不会消耗您的 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;
    }
}

Here is a pause class that will pause for the desired milliseconds and wont consume your CPU resources.

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;
    }
}
莳間冲淡了誓言ζ 2024-08-02 10:33:06

是的,效果很好。

您不必拥有多个线程即可使用 Thread 类中的某些方法。 你总是至少有一个线程。

Yes, that works just fine.

You don't have to have multiple threads to make use of some of the methods in the Thread class. You always have at least one thread.

深府石板幽径 2024-08-02 10:33:06

对于超时,您应该有一个静态易失性布尔值 isRunning 类字段。 当新线程启动时,isRunning 必须变为 true,最后必须变为 false。

主线程应该有一个在您定义的超时期间循环运行 isRunning 的方法。 当超时结束时,您应该实现逻辑。 但是,切勿使用中止线程方法。

暂停一下……没有直接的解决方案。 这取决于您在线程内做什么。 但是,您可以查看 Monitor .等等

For a timeout, you should have a static volatile boolean isRunning class field. When the new thread starts, the isRunning must become true, and at the end must become false.

The main thread should have a method that loops for the isRunning during the timeout you define. When the timeout ends, you should implement the logic. But, never use the abort thread method.

A pause... there isn't a straightforward solution. It depends on what you are doing inside the thread. However, you could look at Monitor.Wait.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文