簡體   English   中英

如何觸發方法在 x 秒后運行?

[英]How do I trigger a method to run after x seconds?

我正在開發一個 C# Windows Forms 應用程序,我需要該方法暫停 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();
}

如果您的應用程序是.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();
}

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());
System.Threading.Tasks.Task.Delay( 60 * 1000 ).ContinueWith( (_) => StartVoid() );

在類級別定義一個Timer實例(有這樣的幾個類 - 對於winforms應用程序,你應該使用System.Windows.Forms.Timer

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

然后在你的方法中添加行來處理它的tick並啟動它:

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

反應性擴展也有一種方法:

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

我們可以使用Task from來做到這一點

System.Threading.Tasks.Task.Factory.StartNew(() =>
        {
            Thread.Sleep(5000);
            this.Invoke(new Action(() => 
                Method1()));
        });

案例 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 class 的方法的 go,則延遲代碼將在后台線程上運行。

  • 展示:
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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM