我从来没有多次使用线程 - 只有少数几次。但今天,我很无聊,想和他们一起玩......并尝试建立一种理解。它看起来像 BackgroundWorkerThread 是一件好事......所以,我尝试制作一个控制台应用程序,简单地写入'Tick'5秒,5次。这就是我想出来的:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
BackgroundWorker bw = new BackgroundWorker();
AlarmClock ac = new AlarmClock(5);
bw.DoWork += ac.StartAlarm;
bw.RunWorkerAsync(5);
bool run = true;
while(run)
{
run = bw.IsBusy;
}
Console.WriteLine("Finished!!");
Console.WriteLine("Press a key...");
Console.ReadKey();
}
}
public class AlarmClock
{
private int noOfTicks;
public AlarmClock (int noOfTicks)
{
this.noOfTicks = noOfTicks;
}
public void StartAlarm(object sender, DoWorkEventArgs e)
{
DateTime start = DateTime.Now;
Console.WriteLine("Alarm set to tick ever 5 seconds.");
int ticks = 0;
bool runMe = true;
while (runMe)
{
if (DateTime.Now.Second % 5 == 0)
{
Console.WriteLine("Tick..");
ticks++;
Thread.Sleep(1000);
}
runMe = ticks < noOfTicks;
}
Console.WriteLine("Aboring thread.");
}
}
}
但它似乎很乱。谁能协助我告诉我应该怎么做?
答案 0 :(得分:2)
或者您只是使用System.Threading.Timer
System.Threading.Timer aTimer = new System.Threading.Timer(OnTimedEvent, null, 5000, 5000);
private static void OnTimedEvent(Object stateInfo)
{
Console.WriteLine("Hi");
}
有关如何防止计时器重启的更多信息,请立即重新启动计时器,在此link禁用定期信令。
要了解.NET中不同计时器之间的差异,请访问此link。
答案 1 :(得分:1)
对于你正在做的事情,你想要使用timer
public static void Main()
{
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed+=new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 5 seconds.
aTimer.Interval=5000;
aTimer.Enabled=true;
Console.WriteLine("Press \'q\' to quit the sample.");
while(Console.Read()!='q');
}
// Specify what you want to happen when the Elapsed event is raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("Hello World!");
}
答案 2 :(得分:1)
如上所述,对于所描述的情况,Timer比BackgroundWorker更有效。但如果你的目标是学习如何使用BackgroundWorker类,你可以这样做:
class Program
{
static void Main()
{
var worker = new BackgroundWorker {WorkerReportsProgress = true};
worker.DoWork += DoWork;
worker.ProgressChanged += ReportProgress;
worker.RunWorkerAsync(5);
Console.ReadKey();
}
private static void DoWork(object sender, DoWorkEventArgs e)
{
int count = (int) e.Argument;
for (int i = 1; i <= count; i++)
{
(sender as BackgroundWorker).ReportProgress(i);
Thread.Sleep(5000); // Do your work
}
}
private static void ReportProgress(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine("Tick " + e.ProgressPercentage);
}
}
答案 3 :(得分:1)
实际上看起来很不错。不计算你的闹钟类,因为它只代表工作代码,它只是做你需要做的事情,你对后台工作者做的唯一事情是添加一个事件,调用一个方法,并等待IsBusy为假。那里什么都没有。
但是你可以改进一些东西。首先,你的while循环不需要一个只设置为IsBusy的运行变量。直接检查IsBusy。此外,你应该在循环中放置一些睡眠,以避免无用的CPU过度负担。事件之间,检查之间的剩余10毫秒将有很大帮助。对于比这更真实的程序,第二个是建议使用RunWorkerCompleted事件在完成时发出警报,而不是经常检查它。这样可以实现更简单,更灵活的代码。
最后一件事,尤其是GUI程序,是了解ProgressChanged事件。在您的工作方法中设置它,并从GUI访问它允许您使用工作线程的进度轻松更新界面。请记住,除了GUI线程之外,您永远不能从任何线程更新GUI。