Qt具有灵巧的功能,可以对Lambda进行定时操作。

可以在延迟后用单行代码执行一个操作:

    QTimer::singleShot(10, [=](){
        // do some stuff
    });

尽管我还没有在C#中找到等效项。

我最接近的是
Timer timer = new Timer();
timer.Interval = 10;
timer.Elapsed += (tsender, args) => {
  // do some stuff
  timer.Stop();
};
timer.Start();

但这远非(在视觉上)干净。

有没有更好的方法来实现这一目标?

用例是通过串行线路将数据发送到某些硬件,单击按钮或执行操作后,通常需要发送命令,并在几毫秒后发送一个数据包。

具有辅助功能的解决方案:
    public void DelayTask(int timeMs, Action lambda)
    {
        System.Timers.Timer timer = new System.Timers.Timer();
        timer.Interval = timeMs;
        timer.Elapsed += (tsender, args) => { lambda.Invoke(); };
        timer.AutoReset = false;
        timer.Start();
    }

致电者
DelayTask(10, () => /* doSomeStuff...*/ );

最佳答案

我想到的最接近的东西是像您建议的帮助器函数之类的东西:

public static class DelayedAction
{
    public static Task RunAsync(TimeSpan delay, Action action)
    {
       return Task.Delay(delay).ContinueWith(t => action(), TaskScheduler.FromCurrentSynchronizationContext());
    }
}

该类的用法将接近您对Qt的了解:
await DelayedAction.RunAsync(TimeSpan.FromSeconds(10), () => /* do stuff */);

更新

如现有SO question中所述,默认情况下ContinueWith不会保留同步上下文。

在当前问题中,lambda正在更新某些UI控件,因此必须在UI线程上运行

为此,调度程序必须在调用方法ContinueWith(TaskScheduler.FromCurrentSynchronizationContext())时指定同步上下文,以确保可以进行这种更新。

关于c# - 如何延迟像QTimer::singleShot这样的C#Action?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53318825/

10-14 22:54
查看更多