[blam] Let the runtime take care of threading
- From: Carlos MartÃn Nieto <cmartin src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [blam] Let the runtime take care of threading
- Date: Sat, 4 Aug 2012 19:06:16 +0000 (UTC)
commit bb23737b5e3c70cd9af5ab48fd02a114eedf3874
Author: Carlos MartÃn Nieto <carlos cmartin tk>
Date: Sat Aug 4 20:55:12 2012 +0200
Let the runtime take care of threading
Use the task capabilities that the runtime gives
us instead of reinenting them poorly
src/Application.cs | 7 +-
src/Channel.cs | 19 ++++++-
src/ChannelCollection.cs | 146 ++++++++++++----------------------------------
src/ChannelGroup.cs | 19 ++++++
4 files changed, 78 insertions(+), 113 deletions(-)
---
diff --git a/src/Application.cs b/src/Application.cs
index e7bbf46..942a7b1 100644
--- a/src/Application.cs
+++ b/src/Application.cs
@@ -170,7 +170,7 @@ namespace Imendio.Blam {
ShowNextUpdateTime();
} else {
if(Conf.Get(Preference.REFRESH_AT_START, false) == true){
- mCollection.RefreshAll();
+ mCollection.RefreshAllAsync();
}
}
@@ -539,7 +539,6 @@ namespace Imendio.Blam {
mainWindow.Hide();
mCollection.SaveToFile ();
ItemStore.Save();
- mCollection.StopAllThreads();
Gtk.Main.Quit();
}
@@ -626,7 +625,7 @@ namespace Imendio.Blam {
public void RefreshChannelActivated(IChannel channel)
{
if (channel != null) {
- mCollection.Refresh (channel);
+ channel.RefreshAsync(null);
}
}
@@ -735,7 +734,7 @@ namespace Imendio.Blam {
private bool TimeoutRefreshAll ()
{
ShowNextUpdateTime();
- mCollection.RefreshAll();
+ mCollection.RefreshAllAsync();
/* Continue until source is removed */
return true;
diff --git a/src/Channel.cs b/src/Channel.cs
index 0508c90..ce2cbf0 100644
--- a/src/Channel.cs
+++ b/src/Channel.cs
@@ -25,6 +25,8 @@ namespace Imendio.Blam {
void Setup();
event ChannelEventHandler Updated;
void RemoveItems();
+ bool Refresh();
+ void RefreshAsync(Action<bool> cb);
}
public class Channel : IChannel {
@@ -302,7 +304,22 @@ namespace Imendio.Blam {
return false;
}
- }
+ delegate bool RefreshDelegate();
+ public bool Refresh()
+ {
+ return FeedUpdater.Update(this);
+ }
+ public void RefreshAsync(Action<bool> cb)
+ {
+ var fun = new RefreshDelegate(Refresh);
+ fun.BeginInvoke(ar => {
+ bool res = fun.EndInvoke(ar);
+ if (cb != null)
+ cb(res);
+ },
+ null);
+ }
+ }
}
diff --git a/src/ChannelCollection.cs b/src/ChannelCollection.cs
index 23aaffc..7f7a427 100644
--- a/src/ChannelCollection.cs
+++ b/src/ChannelCollection.cs
@@ -7,9 +7,11 @@
using System;
using System.Collections;
+using System.Linq;
using System.IO;
using System.Reflection;
using System.Threading;
+using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
@@ -27,8 +29,6 @@ namespace Imendio.Blam {
public string FileName;
- private Queue mQueue;
- private IList mRunningList;
private Object clock = new Object();
private bool mDirty = false;
@@ -84,8 +84,6 @@ namespace Imendio.Blam {
public ChannelCollection ()
{
- mQueue = Queue.Synchronized (new Queue ());
- mRunningList = ArrayList.Synchronized (new ArrayList ());
}
public static ChannelCollection LoadFromFile (string file)
@@ -173,8 +171,8 @@ namespace Imendio.Blam {
}
}
- public void Add (IChannel channel)
- {
+ public void Add (IChannel channel)
+ {
// Not the most efficient way of doing things :)
foreach (Channel ch in mChannels) {
if (channel.Url == ch.Url) {
@@ -187,27 +185,26 @@ namespace Imendio.Blam {
}
mChannels.Add (channel);
- Refresh (channel);
-
- if (ChannelAdded != null) {
- ChannelAdded (channel);
- }
-
- MarkAsDirty(true);
+ channel.RefreshAsync(updated => {
+ MarkAsDirty(true);
+ if (ChannelAdded != null)
+ ChannelAdded (channel);
+ });
}
- public void Add(ChannelGroup group, IChannel channel)
- {
- group.Add(channel);
- Refresh(channel);
+ public void Add(ChannelGroup group, IChannel channel)
+ {
+ group.Add(channel);
+ channel.RefreshAsync(updated => {
+ channel.Updated += Updated;
- channel.Updated += Updated;
- if(ChannelGroupAdded != null){
- ChannelGroupAdded(group, channel);
- }
+ if(ChannelGroupAdded != null){
+ ChannelGroupAdded(group, channel);
+ }
- MarkAsDirty(true);
- }
+ MarkAsDirty(true);
+ });
+ }
public void Updated (IChannel channel)
{
@@ -242,96 +239,29 @@ namespace Imendio.Blam {
MarkAsDirty(true);
}
- public void Refresh (IChannel channel)
- {
- mQueue.Enqueue (channel);
- EmitChannelRefreshStarted (channel);
-
- Thread thread = new Thread (new ThreadStart (UpdateThread));
- mRunningList.Add (thread);
+ delegate void RefreshAllDelegate();
- thread.Start ();
- }
-
- private void QueueChannelRefresh (IChannel channel)
- {
- mQueue.Enqueue (channel);
- EmitChannelRefreshStarted (channel);
- }
-
- private void StartRefreshThreads (int maxNrOfThreads)
- {
- // Only start a maximum of five threads
- for (int i = 0; i < 5 && i < maxNrOfThreads; ++i) {
- Thread thread = new Thread (new ThreadStart (UpdateThread));
- mRunningList.Add (thread);
- thread.Start ();
- }
- }
-
- public void StopAllThreads()
- {
- foreach(Thread t in mRunningList){
- t.Abort();
+ public void RefreshAllAsync()
+ {
+ var fun = new RefreshAllDelegate(RefreshAll);
+ fun.BeginInvoke(fun.EndInvoke, null);
}
- mRunningList.Clear();
- mQueue.Clear();
- }
-
- public void RefreshAll ()
- {
- int nrOfChannels = 0;
-
- foreach (Channel channel in mChannels) {
- QueueChannelRefresh (channel);
- nrOfChannels++;
- }
-
- foreach(ChannelGroup group in Groups){
- foreach(Channel channel in group.Channels){
- QueueChannelRefresh(channel);
- nrOfChannels++;
- }
- }
-
- StartRefreshThreads (nrOfChannels);
- }
-
- private void UpdateThread ()
- {
- while (true) {
- try {
- IChannel tmp = (IChannel) mQueue.Dequeue ();
- Channel channel;
-
- if(tmp is ChannelGroup){
- mRunningList.Remove(Thread.CurrentThread);
- return;
+ public void RefreshAll ()
+ {
+ var all = mChannels.Cast<Channel>();
+ foreach(ChannelGroup group in Groups){
+ all.Union(group.Channels.Cast<Channel>());
}
- channel = tmp as Channel;
- bool updated = FeedUpdater.Update (channel);
-
- if (updated) {
- MarkAsDirty (true);
- }
-
- new MainloopEmitter (this.ChannelRefreshFinished, channel).Emit ();
-#if ENABLE_NOTIFY
- /* Make sure we have something to say and the user isn't watching us */
- if(mQueue.Count == 0 &&
- NrOfUnreadItems != 0 && Application.TheApp.Window.IsActive == false){
- UnreadNotification.NotifyUnreadPosts(NrOfUnreadItems, NrOfNewItems);
- }
-#endif
- } catch (InvalidOperationException) {
- break;
- }
- }
-
- mRunningList.Remove (Thread.CurrentThread);
- }
+ Parallel.ForEach(mChannels.Cast<Channel>(), c => {
+ bool updated = c.Refresh();
+ if (updated) {
+ MarkAsDirty (true);
+ }
+ new MainloopEmitter (this.ChannelRefreshFinished, c).Emit ();
+ });
+ }
private void EmitChannelRefreshStarted (IChannel channel)
{
diff --git a/src/ChannelGroup.cs b/src/ChannelGroup.cs
index 5ff0c20..4c1df3d 100644
--- a/src/ChannelGroup.cs
+++ b/src/ChannelGroup.cs
@@ -7,6 +7,8 @@
using System;
using System.Collections;
using System.Xml.Serialization;
+using System.Threading.Tasks;
+using System.Linq;
namespace Imendio.Blam
{
@@ -157,5 +159,22 @@ namespace Imendio.Blam
}
return null;
}
+
+ public delegate bool RefreshDelegate();
+ public bool Refresh()
+ {
+ Parallel.ForEach(Channels.Cast<Channel>(), c => c.Refresh());
+ return true; // Whatever
+ }
+
+ public void RefreshAsync(Action<bool> cb)
+ {
+ var fun = new RefreshDelegate(Refresh);
+ fun.BeginInvoke(ar => {
+ bool res = fun.EndInvoke(ar);
+ if (cb != null)
+ cb(res);
+ }, null);
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]