开发者

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)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜