我在C#,Silverlight工作。
我需要一种基于某些值(以秒为单位)(或其他时间单位)初始化倒计时的方法,并且在倒计时结束时我需要执行某种方法。
倒计时必须与主要应用程序分开。
答案 0 :(得分:2)
使用Task.Delay
static void SomeMethod()
{
Console.WriteLine("Thread ID = " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("performing an action...");
}
static void Main(string[] args)
{
int someValueInSeconds = 5;
Console.WriteLine("Thread ID = " + Thread.CurrentThread.ManagedThreadId);
Task.Delay(TimeSpan.FromSeconds(someValueInSeconds)).ContinueWith(t => SomeMethod());
// Prevents the app from terminating before the task above completes
Console.WriteLine("Countdown launched. Press a key to exit.");
Console.ReadKey();
}
请注意,您关注的唯一代码是具有Task.Delay
的代码。我已经包含了其他所有内容,以证明操作在倒计时后执行,并在另一个线程上执行,如您所要求的那样。
Aviod 使用Timer类,新的Task。* API提供了相同级别的灵活性和更简单的代码。
答案 1 :(得分:1)
使用System.Timers.Timer对象。订阅Elapsed事件,然后致电Start。
using System.Timers;
...
some method {
...
Timer t = new Timer(duration);
t.Elapsed += new ElapsedEventHandler(handlerMethod);
t.AutoReset = false;
t.Start();
...
}
void handlerMethod(Object sender, ElapsedEventArgs e)
{
...
}
默认情况下(如上所示),Timer将使用ThreadPool
来触发事件。这意味着handlerMethod将不会与您的应用程序在同一个线程上运行。它可能与ThreadPool中的其他线程竞争,但不与池外的线程竞争。您可以设置SynchronizingObject来修改此行为。特别是,如果Elapsed事件调用Windows窗体控件中的方法,则必须在创建控件的同一线程上运行,将SynchronizingObject设置为控件将完成此操作。
答案 2 :(得分:1)
在调用事件处理程序时,不应阻止它们,它们应立即返回。您应该通过Timer,BackgroundWorker或Thread(按此优先顺序)实现它。
参考:
using System;
using System.Windows.Forms;
class MyForm : Form {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.Run(new MyForm());
}
Timer timer;
MyForm() {
timer = new Timer();
count = 10;
timer.Interval = 1000;
timer.Tick += timer_Tick;
timer.Start();
}
protected override void Dispose(bool disposing) {
if (disposing) {
timer.Dispose();
}
base.Dispose(disposing);
}
int count;
void timer_Tick(object sender, EventArgs e) {
Text = "Wait for " + count + " seconds...";
count--;
if (count == 0)
{
timer.Stop();
}
}
}
答案 3 :(得分:1)
DispatcherTimer timer = new DispatcherTimer();
timer.Tick += delegate(object s, EventArgs args)
{
timer.Stop();
// do your work here
};
// 300 ms timer
timer.Interval = new TimeSpan(0, 0, 0, 0, 300);
timer.Start();