如何触发一个方法在x秒后运行?

问题描述 投票:0回答:8

我正在开发一个 C# Windows 窗体应用程序,我需要该方法暂停 30 秒,直到它继续执行下一行代码。我已经尝试过

Thread.Sleep()
,它不适合这个应用程序,我知道我应该使用某种计时器来代替。我搜索了很多,但不知道如何实现计时器。

我的代码如下,任何人都可以告诉我应该如何实现计时器。我已经对我希望该方法暂停的位置发表了评论。

private void start_Vid_Click(object sender, EventArgs e)
{
    if (video.State != StateFlags.Running)
    {
        viewport.Visible = true;
        video.Play();
    }

    //Here I want to wait 30 seconds until the next line of code is triggered

    viewport.Visible = false;
    viewport2.Visible = true;
    pictureBox1.Visible = true;
    start_Webc(); 
    video2.Play();
}
c# timer
8个回答
34
投票

如果您的应用程序是.Net 4.5应用程序,那么使用起来会更容易一些

Task

private async void start_Vid_Click(object sender, EventArgs e)
{
    if (video.State != StateFlags.Running)
    {
        viewport.Visible = true;
        video.Play();
    }

    await Task.Delay(TimeSpan.FromSeconds(30));

    viewport.Visible = false;
    viewport2.Visible = true;
    pictureBox1.Visible = true;
    start_Webc();
    video2.Play();
}

14
投票

Task.Delay 在 .NET 4.0 上不可用,但您可以启动任务,该任务只会休眠 30 秒,稍后您可以再次在 UI 线程上继续:

Task.Factory.StartNew(() => Thread.Sleep(30 * 1000))
            .ContinueWith((t) =>
    {
         viewport.Visible = false;
         viewport2.Visible = true;
         pictureBox1.Visible = true;
         start_Webc(); 
         video2.Play();
    }, TaskScheduler.FromCurrentSynchronizationContext());

6
投票

在类级别定义

Timer
的实例(有一些这样的类 - 对于 winforms 应用程序,您应该使用
System.Windows.Forms.Timer

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

然后在您的方法中添加行来处理其刻度并启动它:

private void start_Vid_Click(object sender, EventArgs e)
{
    if (video.State != StateFlags.Running)
    {
        viewport.Visible = true;
        video.Play();
    }

    myTimer.Tick += (o,ea) => {    
        viewport.Visible = false;
        viewport2.Visible = true;
        pictureBox1.Visible = true;
        start_Webc(); 
        video2.Play();
        myTimer.Stop();
    }
    myTimer.Interval = 5000; // 5 seconds
    myTimer.Start();
}

6
投票
System.Threading.Tasks.Task.Delay( 60 * 1000 ).ContinueWith( (_) => StartVoid() );

4
投票

我们可以使用

中的任务来做到这一点
System.Threading.Tasks.Task.Factory.StartNew(() =>
        {
            Thread.Sleep(5000);
            this.Invoke(new Action(() => 
                Method1()));
        });

3
投票

还有一种反应式扩展的方法:

Observable.Return("Delayed").Delay(TimeSpan.FromSeconds(30)).Subscribe(val => Console.WriteLine("Executing delayed"));

0
投票

WPF案例..

  • WPF 扩展:
public static partial class WpfUtils
{
    public static void RunAfter(double seconds, Action action)
    {
        if (Application.Current.Dispatcher == null)
            return;
        var myTimer = new DispatcherTimer(
            DispatcherPriority.Normal,
            Application.Current.Dispatcher)
        {
            Interval = TimeSpan.FromSeconds(seconds)
        };
        myTimer.Tick += (_, _) =>
        {
            action?.Invoke();
            myTimer.Stop();
        };
        myTimer.Start();
    }
}
  • 用途:
WpfUtils.RunAfter(3, () =>
{
    // some code
    Console.WriteLine("Running after 3 seconds");
});

请注意,此代码将在 UI 线程上运行。另一方面,如果您使用

Task
类中的方法,则延迟的代码将在后台线程上运行。

  • 展示:
Task.Delay(6 * 1000).ContinueWith(_ =>
{
    // this will run in a background-thread
    var b = Thread.CurrentThread.IsBackground;
    Debug.Assert(b);
    Console.WriteLine("3");
});

var timer = new DispatcherTimer
{
    Interval = TimeSpan.FromSeconds(3)
};
timer.Tick += (_, _) =>
{
    // this will run in the UI-thread
    var b = Thread.CurrentThread.IsBackground;
    Debug.Assert(!b);
    Console.WriteLine("2");
    timer.Stop();
};
timer.Start();

Console.WriteLine("1");

// output
// 1
// 2
// 3

0
投票

我用的是这个方法:

  1. Timer
    拖至表单并设置
    Enabled=False
    Interval=YOUR_DELAY
  2. 双击计时器并将您的函数放入其中。在最后一行,添加
    Timer1.Enabled = false
    !
  3. 当您想要开始延迟时,例如单击后等,请通过
    Timer1.Enabled = true
  4. 激活计时器
  5. 完成!

因此,当您单击按钮或某物时,计时器就会启动,并且在运行代码后,它将再次被禁用。

© www.soinside.com 2019 - 2024. All rights reserved.