<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7137885</id><updated>2011-07-07T18:20:29.257-07:00</updated><title type='text'>C# Development</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://csharpdevelop.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7137885/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://csharpdevelop.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jeff WS</name><uri>http://www.blogger.com/profile/07235157260066413391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='7' src='http://www.softwarejuice.com/images/SoftwareJuice-Footer.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7137885.post-108696943786707847</id><published>2004-06-11T08:43:00.000-07:00</published><updated>2004-06-16T21:45:55.390-07:00</updated><title type='text'>Using Thread.Join to Ensure a Worker Thread Has Exited</title><content type='html'>Using threads is difficult. A developers coding complexity increases dramatically. Issues such as reentrance, deadlock and race conditions are difficult to detect and avoid. Creating, using and ending threads all require careful implementation of managing thread lifetimes. &lt;br /&gt;&lt;br /&gt;In this discussion, we look at one way a thread can synchronize itself with another thread waiting for it to complete. This technique can be used as part of an orderly shutdown of worker threads. The System.Threading.Thread class has an instance member called Join that can provide this type of functionality. Join provides several overloads. Using Join is not difficult. But, using it wisely is. &lt;br /&gt;&lt;br /&gt;For the simple Join case, we can call the Join overload that takes no arguments. This call will block until the thread being joined to has ended. The call is simple, but dangerous. Consider when this joined thread never ends! The calling thread would then be hung and would not be able to continue until some other thread interrupted or aborted it. This special case is difficult to code and best avoided if possible.&lt;br /&gt;&lt;br /&gt;Thankfully Join also provides overloads that require a timeout parameter. Their use is preferred. These overloads take either a millisecond or a TimeSpan timeout. They both return a bool that is true to indicated the joined thread has exited, false otherwise.&lt;br /&gt;&lt;h4&gt;&lt;pre&gt;&lt;br /&gt;&lt;-- Example 1 -------------------------------&gt;&lt;br /&gt;&lt;br /&gt;// The semantics here are:&lt;br /&gt;//     The current thread calling Join(), "joins" the myThread thread instance.&lt;br /&gt;//     myThread is the thread being joined to.&lt;br /&gt;//     The current thread is then blocked until the myThread's ThreadStart delegate target &lt;br /&gt;//     has returned control back to the CLR by exiting.&lt;br /&gt;&lt;br /&gt;myThread.Join();  // blocks until myThread completes&lt;br /&gt;&lt;br /&gt;// At this point, myThread has exited.&lt;br /&gt;&lt;br /&gt;&lt;-- Example 2 -------------------------------&gt;&lt;br /&gt;&lt;br /&gt;// Created on some managing thread&lt;br /&gt;ManualResetEvent quit = new ManualResetEvent(false);&lt;br /&gt;// ThreadProc is defined and used as the delegate target.&lt;br /&gt;// Somehow, the ThreadProc has access to quit WaitHandle&lt;br /&gt;Thread t = new Thread(new ThreadStart(ThreadProc));&lt;br /&gt;&lt;br /&gt;// managing thread signals created thread it is time to quit&lt;br /&gt;quit.Set();&lt;br /&gt;&lt;br /&gt;// Assumes the created thread will monitor the quit WaitHandle to know when to quit.&lt;br /&gt;// The amount of time until the thread quits is application dependent.&lt;br /&gt;// Choose an appropriate timeout for the Join below when considering this.&lt;br /&gt;&lt;br /&gt;// later the managing thread waits for the created thread to exit&lt;br /&gt;if (!t.Join(2000)) {&lt;br /&gt;    // report aborting thread&lt;br /&gt;    t.Abort();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/h4&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7137885-108696943786707847?l=csharpdevelop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpdevelop.blogspot.com/feeds/108696943786707847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7137885&amp;postID=108696943786707847' title='82 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7137885/posts/default/108696943786707847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7137885/posts/default/108696943786707847'/><link rel='alternate' type='text/html' href='http://csharpdevelop.blogspot.com/2004/06/using-threadjoin-to-ensure-worker.html' title='Using Thread.Join to Ensure a Worker Thread Has Exited'/><author><name>Jeff WS</name><uri>http://www.blogger.com/profile/07235157260066413391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='7' src='http://www.softwarejuice.com/images/SoftwareJuice-Footer.gif'/></author><thr:total>82</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7137885.post-108646474615958231</id><published>2004-06-05T12:45:00.000-07:00</published><updated>2004-06-07T23:40:00.033-07:00</updated><title type='text'>What happens when an object is created that implements an interface?</title><content type='html'>Start with C# definition of an interface. From the C# specification: "An interface defines a contract. A class or struct that implements an interface must adhere to its contract."&lt;br /&gt;&lt;br /&gt;An interface type declaration simply declares a new type that can be implemented by a class or struct. A classs or structure can implement an interface by inheriting from it then provide the interface member implementations. Another interface can also inherit from an interface type too. This simply requires the class or struct inheriting the interface inheritance family to implement the combined interface members from the entire interface inheritance family. A class or struct can also explicitly derive from multiple interfaces. C# supports the notion of "single" inheritance. This means "single" implementation inheritance. But, a class or struct can derive from multiple interfaces. This is because interfaces do not provide any implementation. &lt;br /&gt;&lt;br /&gt;At runtime, a interface reference can be refer to. You can declare a reference to an interface, but you cannot explicit instantiate an interface. This is because, an interface type, by itself, does not provide any implementation. To refer to an interface, you must instantiate the class or struct that implemented the interface. Once this is created, you can assign this implementing type to a reference of the interface type it implemented. That is allowed because of the implicit type conversion rules. These rules partially state that a derived type may be implicitly converted to another inherited type. So, any class or struct inheriting from an interface and instantiated at runtime can be implicitly converted to the interface type it inherited from. But, nothing really changes with this instantiated type when it is assigned to one its inherited interface types. The real runtime type is still the same type that implemented the interface. &lt;br /&gt;&lt;br /&gt;At runtime using the interface reference simply restricts the members you can call on the runtime type's instance that implemented the interface. The restriction allows only the interface's members and any of its inherited interface methods. You can verify this with the following code:&lt;br /&gt;&lt;h4&gt;&lt;pre&gt;&lt;br /&gt;interface IFooBase {&lt;br /&gt;    void FooBase();&lt;br /&gt;}&lt;br /&gt;	&lt;br /&gt;interface IFoo : IFooBase {&lt;br /&gt;	void Bar();&lt;br /&gt;}&lt;br /&gt;	&lt;br /&gt;public class FooImpl : IFoo {&lt;br /&gt;	public void FooBase() {&lt;br /&gt;	 	Console.WriteLine("FooImpl.FooBase called.");&lt;br /&gt;	 }&lt;br /&gt;	public void Bar() {&lt;br /&gt;	 	Console.WriteLine("FooImpl.Bar called.");&lt;br /&gt;	 }&lt;br /&gt;	public void Bar2() {&lt;br /&gt;	 	Console.WriteLine("FooImpl.Bar2 called.");&lt;br /&gt;	 }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Then in some client code:&lt;br /&gt;IFoo fii = new FooImpl();&lt;br /&gt;fii.FooBase();&lt;br /&gt;fii.Bar();&lt;br /&gt;fii.Bar2(); // Compile error: "IFoo does not contain a definition for Bar2&lt;br /&gt;&lt;br /&gt;Console.WriteLine("fii's runtime type is: {0}", fii.GetType());&lt;br /&gt;&lt;br /&gt;// ...&lt;br /&gt;&lt;br /&gt;// After deleting the code for the compile error above, compiling and running&lt;br /&gt;// the console output is:&lt;br /&gt;FooImpl.FooBase called.&lt;br /&gt;FooImpl.Bar called.&lt;br /&gt;fii's runtime type is: FooImpl&lt;br /&gt;&lt;/pre&gt;&lt;/h4&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7137885-108646474615958231?l=csharpdevelop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpdevelop.blogspot.com/feeds/108646474615958231/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7137885&amp;postID=108646474615958231' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7137885/posts/default/108646474615958231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7137885/posts/default/108646474615958231'/><link rel='alternate' type='text/html' href='http://csharpdevelop.blogspot.com/2004/06/what-happens-when-object-is-created.html' title='What happens when an object is created that implements an interface?'/><author><name>Jeff WS</name><uri>http://www.blogger.com/profile/07235157260066413391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='7' src='http://www.softwarejuice.com/images/SoftwareJuice-Footer.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7137885.post-108633102550314402</id><published>2004-06-03T23:09:00.000-07:00</published><updated>2004-06-04T21:51:31.623-07:00</updated><title type='text'>Protecting against InvalidOperationException when dequeueing from an empty queue</title><content type='html'>MSDN documents that Queue.Dequeue()ing from an empty System.Collections.Queue will throw an exception of type InvalidOperationException. They also suggest as one alternative to wrap the call in a try/catch and be done! But a simple check to Queue.Count before Queue.Dequeue()ing will eliminate the performance penalty incurred for the thrown exception. It is also a proactive coding measure that doesn't add too much complex and removes the need for the call specific catch handler. But, if we do not implement this correctly, the exception can still be thrown. &lt;p/&gt;Why? &lt;p/&gt;Because of the race condition that exists between the separate calls Count and Dequeue. Only a new Queue created using Queue.Synchronized is synchronized. Queue.Synchronized returns a synchronized wrapper for a new'd Queue passed to it. But, Queue can only synchronize access to itself during the life of a single call. To fix and remove the race condition, we need to lock access for our external code to call Queue.Count then Queue.Dequeue before releasing the lock. Synchronizing a Queue (which implements ICollection) should always synchronize the return from Queue.SyncRoot and not the Queue instance. This is to support derivations of a synchronized Queue which can also synchronize on it too. &lt;p&gt;To simply client access we can provide a simple wrapper class that implements the correct code for locking the Queue for both calls as follows:&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;pre&gt;&lt;br /&gt;public class Shared {&lt;br /&gt;	private Queue q;&lt;br /&gt;	private ManualResetEvent workToDo;&lt;br /&gt;&lt;br /&gt;	public Shared(ManualResetEvent evt) {&lt;br /&gt;		workToDo = evt;&lt;br /&gt;		q = Queue.Synchronized(new Queue());&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	public void Enqueue(object o) {&lt;br /&gt;		q.Enqueue(o);&lt;br /&gt;		workToDo.Set();&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	public object Dequeue() {&lt;br /&gt;		object o = null;&lt;br /&gt;&lt;br /&gt;		// lock q access&lt;br /&gt;		lock(q.SyncRoot) {&lt;br /&gt;			int c = q.Count;&lt;br /&gt;			// check to see if empty&lt;br /&gt;			if (c &gt; 0) {&lt;br /&gt;				o = q.Dequeue();&lt;br /&gt;				if (c == 1) {&lt;br /&gt;					// only had one item and Dequeue just removed it, so signal&lt;br /&gt;					workToDo.Reset();&lt;br /&gt;				}&lt;br /&gt;			}&lt;br /&gt;		}&lt;br /&gt;&lt;br /&gt;		return o;&lt;br /&gt;	}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/h4&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7137885-108633102550314402?l=csharpdevelop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpdevelop.blogspot.com/feeds/108633102550314402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7137885&amp;postID=108633102550314402' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7137885/posts/default/108633102550314402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7137885/posts/default/108633102550314402'/><link rel='alternate' type='text/html' href='http://csharpdevelop.blogspot.com/2004/06/protecting-against-invalidoperationexc.html' title='Protecting against InvalidOperationException when dequeueing from an empty queue'/><author><name>Jeff WS</name><uri>http://www.blogger.com/profile/07235157260066413391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='7' src='http://www.softwarejuice.com/images/SoftwareJuice-Footer.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7137885.post-108593837930046346</id><published>2004-05-30T10:20:00.000-07:00</published><updated>2004-05-30T10:45:18.846-07:00</updated><title type='text'>Writing an infinite loop?</title><content type='html'>Application code solutions sometimes have use for infinite loops. Consider the following:&lt;br /&gt;&lt;h4&gt;&lt;pre&gt;&lt;br /&gt;    for(;;);&lt;br /&gt;&lt;br /&gt;    // or&lt;br /&gt;&lt;br /&gt;    while(true);&lt;br /&gt;&lt;/pre&gt;&lt;/h4&gt;&lt;br /&gt;&lt;p/&gt;&lt;br /&gt;But this code is &lt;em&gt;dangerous&lt;/em&gt; because once executed the running thread can never get past this code (unless another thread forces a Thread.Abort on this thread). Instead this code should be written as follows:&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;pre&gt;&lt;br /&gt;    // psuedo code&lt;br /&gt;    while(true) {&lt;br /&gt;        if ( some quit condition is true) break;&lt;br /&gt;        // do a piece of the work here&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;But, where would code like this be used? &lt;br/&gt;&lt;br /&gt;This kind of code occurs quite a bit in worker threads waiting for some work to do. It is a common code pattern. All code in the looping statements body is critical. The "quit condition" must be checked frequently. This implies that the work to do must be short. Usually this is one smaller chuck of work out of the larger set of work it was given to accomplish. &lt;br /&gt;&lt;br/&gt;&lt;br /&gt;What causes the quit condition to become true?&lt;br/&gt;&lt;br /&gt;That is always application specific, but usually some other thread in the application eventually sets this quit condition to true.&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;What if there is no work? Won't the thread spin and waste CPU cycles?&lt;br/&gt;&lt;br /&gt;Yes. If no work is available to do and the quit condition is not true, this loop should sleep. In C#, Thread.Sleep can be used with a timeout of at least 1ms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7137885-108593837930046346?l=csharpdevelop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpdevelop.blogspot.com/feeds/108593837930046346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7137885&amp;postID=108593837930046346' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7137885/posts/default/108593837930046346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7137885/posts/default/108593837930046346'/><link rel='alternate' type='text/html' href='http://csharpdevelop.blogspot.com/2004/05/writing-infinite-loop.html' title='Writing an infinite loop?'/><author><name>Jeff WS</name><uri>http://www.blogger.com/profile/07235157260066413391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='7' src='http://www.softwarejuice.com/images/SoftwareJuice-Footer.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7137885.post-108575914747177201</id><published>2004-05-28T08:39:00.000-07:00</published><updated>2004-05-28T09:35:50.690-07:00</updated><title type='text'>Thread safe access to a System.Windows.Forms.Control</title><content type='html'>From the MSDN documentation (re. April 2004 edition), the only methods that can be safely called from any thread are: Control.BeginInvoke/EndInvoke/Invoke/InvokeRequired/CreateGraphics. &lt;br /&gt;&lt;br /&gt;Control.Invoke is a synchronous call that can be safely called to update a Control. The call can be made from any thread and is passed a delegate (of any type). An overload of this method takes an object[] as the parameters your delegate requireds. The return from the Invoke is the return from your delegate - if any. These two forms of Invoke are:&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;pre&gt;&lt;br /&gt;public object Invoke(delegate method);&lt;br /&gt;public virtual object Invoke(delegate method, object[] args);&lt;br /&gt;&lt;/pre&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;The following is a code sample of using a type that can call Control.Invoke from any thread.&lt;br /&gt;&lt;h4&gt;&lt;pre&gt;&lt;br /&gt;// Using the second overload of Invoke from above&lt;br /&gt;class MyClass {&lt;br /&gt;    private delegate void UpdateListbox(string msg);&lt;br /&gt;    private ListBox lb;&lt;br /&gt;&lt;br /&gt;    // This ctor can be called on any thread and passed the reference to the Listbox&lt;br /&gt;    MyClass(ListBox lb) {&lt;br /&gt;        this.lb = lb;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // Any thread can call this method which indirectly updates the Listbox using Control.Invoke.&lt;br /&gt;    // The call is synchronous, so the calling thread is blocked until the Listbox is update.&lt;br /&gt;    // Consider Control.BeginInvoke for the asynchronous (non-blocking) solution.&lt;br /&gt;    void UpdateLB(string newMsg) {&lt;br /&gt;        UpdateListbox ulb = new UpdateListbox(this.OnUpdate);&lt;br /&gt;        lb.Invoke(ulb, new object[] { newMsg });&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // Do not directly call this method.&lt;br /&gt;    // This method is designed to use only as a delegate target that is invoke on the thread that &lt;br /&gt;    // created the Listbox.&lt;br /&gt;    private void OnUpdate(string msg) {&lt;br /&gt;        lb.Items.Add(msg);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/h4&gt;&lt;br /&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7137885-108575914747177201?l=csharpdevelop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpdevelop.blogspot.com/feeds/108575914747177201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7137885&amp;postID=108575914747177201' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7137885/posts/default/108575914747177201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7137885/posts/default/108575914747177201'/><link rel='alternate' type='text/html' href='http://csharpdevelop.blogspot.com/2004/05/thread-safe-access-to.html' title='Thread safe access to a System.Windows.Forms.Control'/><author><name>Jeff WS</name><uri>http://www.blogger.com/profile/07235157260066413391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='7' src='http://www.softwarejuice.com/images/SoftwareJuice-Footer.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7137885.post-108575873831771599</id><published>2004-05-28T08:37:00.000-07:00</published><updated>2004-05-28T08:38:58.316-07:00</updated><title type='text'>Creating a synchronized Queue</title><content type='html'>using System.Collections;&lt;br /&gt;&lt;br /&gt;// myQueue is now protected, but only during the a method call&lt;br /&gt;Queue myQueue = Queue.Synchronized(new Queue());&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7137885-108575873831771599?l=csharpdevelop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpdevelop.blogspot.com/feeds/108575873831771599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7137885&amp;postID=108575873831771599' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7137885/posts/default/108575873831771599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7137885/posts/default/108575873831771599'/><link rel='alternate' type='text/html' href='http://csharpdevelop.blogspot.com/2004/05/creating-synchronized-queue.html' title='Creating a synchronized Queue'/><author><name>Jeff WS</name><uri>http://www.blogger.com/profile/07235157260066413391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='7' src='http://www.softwarejuice.com/images/SoftwareJuice-Footer.gif'/></author><thr:total>0</thr:total></entry></feed>
