简体   繁体   English

在不阻塞主线程的情况下等待一段时间

[英]Wait for a while without blocking main thread

I wish my method to wait about 500 ms and then check if some flag has changed.我希望我的方法等待大约 500 毫秒,然后检查某些标志是否已更改。 How to complete this without blocking the rest of my application?如何在不阻塞应用程序的其余部分的情况下完成此操作?

Thread.Sleep(500) will force the current thread to wait 500ms. Thread.Sleep(500)将强制当前线程等待 500 毫秒。 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:在这种情况下,您将需要使用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!");
}

You can set AutoReset to true (or not set it at all) if you want the timer to repeat itself.如果您希望计时器自动重复,您可以将AutoReset设置为 true(或根本不设置)。

You can use await Task.Delay(500);您可以使用await Task.Delay(500); without blocking the thread like Sleep does, and with a lot less code than a Timer.不会像Sleep那样阻塞线程,并且代码比 Timer 少很多。

I don't really understand the question.我真的不明白这个问题。

If you want to block before checking, use Thread.Sleep(500);如果要在检查前阻塞,请使用Thread.Sleep(500);

If you want to check asynchronously every x seconds, you can use a Timer to execute a handler every x milliseconds.如果要每 x 秒异步检查一次,可以使用Timer每 x 毫秒执行一次处理程序。

This will not block your current thread.这不会阻塞您当前的线程。

如果有问题的方法与应用程序的其余部分在不同的线程上执行,请执行以下操作:

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.这不会阻塞应用程序的其余部分,只会阻塞正在运行您的方法的线程。

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

Asynchron Task:异步任务:

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

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

I've recently been struggling with the same issue where I needed an action to be run on schedule without blocking the UI.我最近一直在努力解决同样的问题,我需要在不阻塞 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);
        }
    });
}

In a WinForms application, when I want to wait on the main thread without blocking the app, I usually use在 WinForms 应用程序中,当我想在主线程上等待而不阻塞应用程序时,我通常使用

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM