等待一段时间,不阻塞主线程

发布于 2024-12-20 23:33:45 字数 67 浏览 4 评论 0原文

我希望我的方法等待大约 500 毫秒,然后检查某些标志是否已更改。如何在不阻止我的应用程序的其余部分的情况下完成此操作?

I wish my method to wait about 500 ms and then check if some flag has changed. How to complete this without blocking the rest of my application?

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

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

发布评论

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

评论(9

与君绝 2024-12-27 23:33:45

您可以使用 await Task.Delay(500);,而不会像 Sleep 那样阻塞线程,并且代码比 Timer 少得多。

You can use await Task.Delay(500); without blocking the thread like Sleep does, and with a lot less code than a Timer.

盛夏已如深秋| 2024-12-27 23:33:45

Thread.Sleep(500) 将强制当前线程等待 500 毫秒。它可以工作,但如果您的整个应用程序在一个线程上运行,则这不是您想要的。

在这种情况下,您需要使用 Timer,如下所示:

using System.Timers;

void Main()
{
    Timer t = new Timer();
    t.Interval = 500; // In milliseconds
    t.AutoReset = false; // Stops it from repeating
    t.Elapsed += new ElapsedEventHandler(TimerElapsed);
    t.Start();
}

void TimerElapsed(object sender, ElapsedEventArgs e)
{
    Console.WriteLine("Hello, world!");
}

如果您希望计时器重复自己。

Thread.Sleep(500) will force the current thread to wait 500ms. It works, but it's not what you want if your entire application is running on one thread.

In that case, you'll want to use a Timer, like so:

using System.Timers;

void Main()
{
    Timer t = new Timer();
    t.Interval = 500; // In milliseconds
    t.AutoReset = false; // Stops it from repeating
    t.Elapsed += new ElapsedEventHandler(TimerElapsed);
    t.Start();
}

void TimerElapsed(object sender, ElapsedEventArgs e)
{
    Console.WriteLine("Hello, world!");
}

You can set AutoReset to true (or not set it at all) if you want the timer to repeat itself.

草莓酥 2024-12-27 23:33:45

我不太明白这个问题。

如果您想在检查之前阻塞,请使用 Thread.Sleep(500);

如果您想每 x 秒异步检查一次,您可以使用 Timer 每 x 毫秒执行一次处理程序。

这不会阻塞您当前的线程。

I don't really understand the question.

If you want to block before checking, use Thread.Sleep(500);

If you want to check asynchronously every x seconds, you can use a Timer to execute a handler every x milliseconds.

This will not block your current thread.

眉目亦如画i 2024-12-27 23:33:45

如果相关方法与应用程序的其余部分在不同的线程上执行,则执行以下操作:

Thread.Sleep(500);

If the method in question is executing on a different thread than the rest of your application, then do the following:

Thread.Sleep(500);
作业与我同在 2024-12-27 23:33:45
System.Threading.Thread.Sleep(500);

更新

这不会阻塞应用程序的其余部分,只会阻塞正在运行您的方法的线程。

System.Threading.Thread.Sleep(500);

Update

This won't block the rest of your application, just the thread that is running your method.

千年*琉璃梦 2024-12-27 23:33:45

我最近一直在努力解决同样的问题,我需要按计划运行一个操作而不阻塞用户界面。

这是我的解决方案:

private void Button_Click(object sender, RoutedEventArgs e)
{
    RunOnSchedule(interval, cancellationToken);
}

private void RunOnSchedule(int interval, CancellationToken cancellationToken)
{
    // Start the task you want to run on schedule
    TaskToRunOnSchedule(args);
    Task.Run(async () => 
    {
        // This loop checks if the task was requested to be cancelled every 1000 ms
        for (int x = 0; x < interval; x+=1000)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                break;
            }

            await Task.Delay(1000);
        }
    }).GetAwaiter().OnCompleted(() =>
    {
        // Once the task for delaying is completed, check once more if cancellation is requested, as you will reach this point regardless of if it was cancelled or not.
        if (!cancellationToken.IsCancellationRequested)
        {
            // Run this method again
            RunOnSchedule(interval, cancellationToken);
        }
    });
}

I've recently been struggling with the same issue where I needed an action to be run on schedule without blocking the UI.

Here's my solution:

private void Button_Click(object sender, RoutedEventArgs e)
{
    RunOnSchedule(interval, cancellationToken);
}

private void RunOnSchedule(int interval, CancellationToken cancellationToken)
{
    // Start the task you want to run on schedule
    TaskToRunOnSchedule(args);
    Task.Run(async () => 
    {
        // This loop checks if the task was requested to be cancelled every 1000 ms
        for (int x = 0; x < interval; x+=1000)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                break;
            }

            await Task.Delay(1000);
        }
    }).GetAwaiter().OnCompleted(() =>
    {
        // Once the task for delaying is completed, check once more if cancellation is requested, as you will reach this point regardless of if it was cancelled or not.
        if (!cancellationToken.IsCancellationRequested)
        {
            // Run this method again
            RunOnSchedule(interval, cancellationToken);
        }
    });
}
画中仙 2024-12-27 23:33:45

使用计时器应该可以解决问题,这是一个示例

如果您需要使用线程,那么

void Main()
{
    System.Threading.Thread check= new System.Threading.Thread(CheckMethod);
    check.Start();
}

private void CheckMethod()
{
     //Code
     Thread.Sleep(500);
}

Using a timer should do the trick

if you need to use a thread then here is an example

void Main()
{
    System.Threading.Thread check= new System.Threading.Thread(CheckMethod);
    check.Start();
}

private void CheckMethod()
{
     //Code
     Thread.Sleep(500);
}
剪不断理还乱 2024-12-27 23:33:45

异步任务:

 var task = new Task (() => function_test()); task.Start();

public void function_test() { `Wait for 5000 miliseconds`   Task.Delay(5000);` }

Asynchron Task:

 var task = new Task (() => function_test()); task.Start();

public void function_test() { `Wait for 5000 miliseconds`   Task.Delay(5000);` }
野の 2024-12-27 23:33:45

在 WinForms 应用程序中,当我想在主线程上等待而不阻塞应用程序时,我通常使用

private void Wait (double milliseconds)
{
    DateTime next = System.DateTime.Now.AddMilliseconds(milliseconds);
    while (next > System.DateTime.Now)
        Application.DoEvents();
}

In a WinForms application, when I want to wait on the main thread without blocking the app, I usually use

private void Wait (double milliseconds)
{
    DateTime next = System.DateTime.Now.AddMilliseconds(milliseconds);
    while (next > System.DateTime.Now)
        Application.DoEvents();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文