Click here to Skip to main content
15,887,683 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi codeproject-community!

I'm just diggin' into the TAP and I'm hoping you can help me with a problem.

Let me first explain what I want to achieve:
I want to read from a RSS-feed every 10 seconds and want to write it's items to output it somehow on my form.

My idea:
I wrote an RssReader which has the async method GetAllRssItems()...
I just could call it from my UI-Thread by calling

C#
reader.GetRssItems().ContinueWith((task) =>
{
    if (task.Exception == null)
    {
        lock (guiListRssItems)
        {
            guiListRssItems.Clear();
            foreach (RssItem item in task.Result)
            {
                guiListRssItems.Add(item);
            }
        }
    }
});


Now this should be executed every 10 seconds (and I don't want to use timers, there must be another way ;) )

So I thought about packing my call of GetRssItems into another task, something like that:

C#
Task poller = new Task(() =>
            {
                RssReader.IRssReader reader = new RssReader.RssReader("http://www.computerbase.de/rss/news.xml");
                while (!cancellationToken.IsCancellationRequested)
                {
                    reader.GetRssItems().ContinueWith((task) =>
                    {
                        if (task.Exception == null)
                        {
                            lock (guiListRssItems)
                            {
                                guiListRssItems.Clear();
                                foreach (RssItem item in task.Result)
                                {
                                    guiListRssItems.Add(item);
                                }
                            }
                        }
                    });
                    // here i would like to wait for GetRssItems to finish and then to say poller.wait(5000) or something like that :)
                }
            }, cancellationToken);
poller.Start();


Does anybody of you have an idea how to achieve this?
My two main problems in this scenary are:
--- GetRssItems is exectued asynchron, how could I wait for it?
--- How to put poller to sleep for 5 seconds

Thanks in advance!

Markus
Posted
Updated 22-Nov-13 2:50am
v2
Comments
Sergey Alexandrovich Kryukov 22-Nov-13 9:54am    
Is the site providing RSS feed yours, or it's given, you need to track it?
What is the type of the application where you want to do the RSS polling?
—SA
NeonMika 22-Nov-13 15:00pm    
It's just a little project for university to learn TAP.
It shouldn't matter which RSS feed it is.
But I found out a solution myself, but thanks for asking :)

And why can't you just use

System.Threading.Thread.Sleep(10000);


in the

while (!cancellationToken.IsCancellationRequested)


Block?

As far as how to wait for the GetRssItems you can use the ContinueWith to call a 'finish' or 'next'

I have this

C#
private void StartTask(long taskId, Action workToDo)
       {
           try
           {
               Task task = new Task(workToDo);
               this.taskIdList.Add(taskId);
               task.ContinueWith(result => this.taskIdList.Remove(taskId));
               task.Start();
               this.EventLog.WriteEntry("Started Task Id " + taskId.ToString() + "\n", System.Diagnostics.EventLogEntryType.Information);
               Debug.WriteLine("Task List Count:" + this.taskIdList.Count.ToString());
           }
           catch (Exception ex)
           {
               this.EventLog.WriteEntry(" Exception thrown. Task Id:" + taskId.ToString() + "\n");
               this.SetTaskException(taskId, "Exception thrown performing task.", ex);
           }
       }



When the thread ends, it comes back and removes itself from the list of active threads

task.ContinueWith(result => this.taskIdList.Remove(taskId));


you can do what ever you want at that point.
 
Share this answer
 
Comments
NeonMika 22-Nov-13 14:53pm    
Sorry, I didn't mention this. The poller task should run on the UI task so there is no cross-thread access on the list.
See my current solution if you want to know how i fixed it.

Futher I heard that not every task has it's own thread. So it's no good practice to put a thread to sleep inside a Task, because it could put other Tasks also to sleep...

But thanks for your input! :)
Okay, after reading some blogs i found some solution that work's pretty good for me:

C#
private Action<Task> getRss = null;
private TaskScheduler ui = TaskScheduler.FromCurrentSynchronizationContext();
public ObservableCollection<t> GuiListRssItems = new ObservableCollection<t>();
private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
private IReader<T> reader;

getRss = (taskIgnored) =>
    reader.GetItems().ContinueWith((task, state) =>
    {
        if (task.Exception == null && !cancellationTokenSource.Token.IsCancellationRequested)
        {
            foreach (T item in task.Result)
            {
                GuiListRssItems.Add(item);
            }
            Task.Delay(4000).ContinueWith(getRss, ui);
        }
    }, null, cancellationTokenSource.Token, TaskContinuationOptions.ExecuteSynchronously, ui);</t></t>


I can start this for example with this:
C#
Task.Delay(1).ContinueWith(getRss, ui);


And I can cancle it with
C#
cancellationTokenSource.Cancle()
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900