Making an method execute on interval in Winforms in C#
I’m making an RSS reader, I want it to be able to update at a given interval of time.
I’m not interested in using the Winforms Timer component.
I was more thinking about using the System.Threading.Timer
.
The method I want to execute on an interval looks like this:
public void getNews()
{
for (int i2 = 0; i2 < urlList.Count; i2++)
{
//Creates a XmlTextReader which reads from the url entered in input field
rssReader = new XmlTextReader(urlList[i2]);
//Creates an xml doc to save the content of the entered path
rssDoc = new XmlDocument();
//Loads the xml content from the reader into a XmlDocument
rssDoc.Load(rssReader);
//Make a loop to search for the <rss> tag
for (int i = 0; i < rssDoc.ChildNodes.Count; i++)
{
//If the childenode is the rss tag
if (rssDoc.ChildNodes[i].Name == "rss")
{
//the <rss> tag is found, and we know where it is
nodeRss = rssDoc.ChildNodes[i];
}
}
//Make a loop to search for the <channel> tag
for (int i = 0; i < nodeRss.ChildNodes.Count; i++)
{
//If the childnode is the channel tag
if (nodeRss.ChildNodes[i].Name == "channel")
{
//The channel tag is found and we know where it is
nodeChannel = nodeRss.ChildNodes[i];
}
}
//Make a loop to search for the <item> tag
for (int i = 0; i < nodeChannel.ChildNodes.Count; i++)
{
//If the childnode is the item tag
if (nodeChannel.ChildNodes[i].Name == "item")
{
//the item tag is found, and we know where it is
nodeItem = nodeChannel.ChildNodes[i];
//Creates a new row in the LstView which contains information from inside the nodes
rowNews = new ListViewItem();
rowNews.Text = nodeItem["title"].InnerText;
rowNews.SubItems.Add(nodeItem["l开发者_C百科ink"].InnerText);
if (this.lstView.InvokeRequired)
{
AddItemCallback d = new AddItemCallback(getNews);
this.Invoke(d);
return;
}
lstView.Items.Add(rowNews);
}
}
}
}
This is the button, that executes the method:
private void btnRead_Click(object sender, EventArgs e)
{
lstView.Items.Clear();
Thread myThread = new Thread(getNews);
myThread.Start();
}
How do I execute my getNews()
method on a specific interval? Examples with my code are very appreciated.
User Timer Control and write code in Tick event... http://www.c-sharpcorner.com/UploadFile/mahesh/WorkingwithTimerControlinCSharp11302005054911AM/WorkingwithTimerControlinCSharp.aspx
I would start a new thread and sleep for the specified interval at the end of it.
for example
you would have a member variable for whether the process is running and the interval
private bool _isRunning = false;
private int _interval = 1000;
then in your start method create a new thread
public void Start()
{
ThreadStart oThreadStart = new ThreadStart(DoWork);
Thread t = new Thread(oThreadStart);
_isRunning = true;
t.Start();
}
public void Stop()
{
_isRunning = false;
}
private void DoWork()
{
while(_isRunning)
{
// do work
Thread.Sleep(_interval);
}
Thread.CurrentThread.Join();
}
You then have all processing on one thread and it sleeps while not in use (eg waiting for the next 'tick')
also, using this method prevents the possibility of a second tick event being fired until the first one has finished processing
I like the Reactive Extensions for these things.
var observable = Observable.Interval(TimeSpan.FromSeconds(2)); // Interval in seconds
var subscription = observable.Subscribe(_ => getNews());
// Or if it does not work then try this:
var subscription = observable.ObserveOnWindowsForms().Subscribe(_ => getNews());
using (subscription)
{
Console.WriteLine("Press any key to stop...");
Console.ReadKey();
}
Instead of stopping with a console key press, you can call .Dispose()
on subscription
and delete the whole using
block.
For testing this approach, try replacing _ => getNews()
with Console.WriteLine
and then you will see how it works :) (it is a example from http://rxwiki.wikidot.com/101samples)
精彩评论