如何异步等待x秒然后执行某些操作?

Den*_*s G 20 c# forms sleep wait winforms

我知道有Thread.SleepSystem.Windows.Forms.TimerMonitor.Wait在C#和Windows窗体.我似乎无法弄清楚如何等待X秒然后做其他事情 - 没有锁定线程.

我有一个带按钮的表格.单击按钮,计时器将启动并等待5秒钟.在这5秒钟后,表格上的其他一些控件显示为绿色.使用时Thread.Sleep,整个应用程序将在5秒内无响应 - 所以我如何"在5秒后做一些事情"?

eFl*_*loh 32

(由Ben转录为评论)

只需使用System.Windows.Forms.Timer.将计时器设置为5秒,然后处理Tick事件.当事件发生时,做那件事.

...并在执行oder工作之前禁用计时器(IsEnabled = false)以抑制秒.

Tick事件可能在另一个无法修改你的gui的线程上执行,你可以抓住这个:

private System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();

    private void StartAsyncTimedWork()
    {
        myTimer.Interval = 5000;
        myTimer.Tick += new EventHandler(myTimer_Tick);
        myTimer.Start();
    }

    private void myTimer_Tick(object sender, EventArgs e)
    {
        if (this.InvokeRequired)
        {
            /* Not on UI thread, reenter there... */
            this.BeginInvoke(new EventHandler(myTimer_Tick), sender, e);
        }
        else
        {
            lock (myTimer)
            {
                /* only work when this is no reentry while we are already working */
                if (this.myTimer.Enabled)
                {
                    this.myTimer.Stop();
                    this.doMyDelayedWork();
                    this.myTimer.Start(); /* optionally restart for periodic work */
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

只是为了完整性:使用async/await,可以延迟执行非常简单的操作(一次性,不再重复调用):

private async Task delayedWork()
{
    await Task.Delay(5000);
    this.doMyDelayedWork();
}

//This could be a button click event handler or the like */
private void StartAsyncTimedWork()
{
    Task ignoredAwaitableResult = this.delayedWork();
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅MSDN中的"async和await".


PVi*_*itt 10

您可以启动执行操作的异步任务:

Task.Factory.StartNew(()=>
{
    Thread.Sleep(5000);
    form.Invoke(new Action(()=>DoSomething()));
});
Run Code Online (Sandbox Code Playgroud)

[编辑]

要传递间隔,只需将其存储在变量中:

int interval = 5000;
Task.Factory.StartNew(()=>
{
    Thread.Sleep(interval);
    form.Invoke(new Action(()=>DoSomething()));
});
Run Code Online (Sandbox Code Playgroud)

[/编辑]

  • 不是个好主意.你绑架了PoolThread 5秒钟.然后你只需使用Invoke()来关闭线程. (2认同)

mac*_*Jun 9

你有没有尝试过

public static Task Delay(
    int millisecondsDelay
)
Run Code Online (Sandbox Code Playgroud)

您可以这样使用:

await Task.Delay(5000);
Run Code Online (Sandbox Code Playgroud)

参考:https : //msdn.microsoft.com/zh-cn/library/hh194873(v=vs.110).aspx


Mas*_*uri 8

您可以按照您希望的方式等待 UI 线程。

Task.Factory.StartNew(async() =>
{
    await Task.Delay(2000);

    // it only works in WPF
    Application.Current.Dispatcher.Invoke(() =>
    {
        // Do something on the UI thread.
    });
});
Run Code Online (Sandbox Code Playgroud)

如果您使用 .Net Framework 4.5 或更高版本,您可以使用Task.Run而不是像Task.Factory.StartNew下面这样。

int millisecondsDelay = 2000;

Task.Run(async() =>
{
    await Task.Delay(millisecondsDelay);

    // it only works in WPF
    Application.Current.Dispatcher.Invoke(() =>
    {
        // Do something on the UI thread.
    });
});
Run Code Online (Sandbox Code Playgroud)