Mysteries of the NET Framework: Question 4

Last post 10-27-2008, 3:32 PM by Klaus Gebhardt. 19 replies.
Page 1 of 2 (20 items)   1 2 Next >
Sort Posts: Previous Next
  •  09-23-2008, 3:40 AM Post number 69672

    Mysteries of the NET Framework: Question 4

    When is it a good idea to start using more than one thread?
    (See the article Mysteries of The Net Framework)
  •  09-23-2008, 9:26 AM Post number 69677 in reply to post number 69672

    Re: Mysteries of the NET Framework: Question 4

    Although it's extremely rare when I've had to use more than a single threaded app, the last one I built used two threads.  One for the UI and one that handled a long-running (about 3 minutes) process that the user kicked off from within their UI.

    Once it was complete, it made a callback to a UI method to alert the user that the process had completed.

  •  09-23-2008, 4:46 PM Post number 69682 in reply to post number 69672

    • Damon is not online. Last active: 11-26-2008, 11:06 AM Damon
    • Top 10 Contributor
    • Joined on 06-26-2006
    • Dallas, TX
    • Acorn Archimedes

    Re: Mysteries of the NET Framework: Question 4

    Simple:  when one thread isn't fast enough for you =]
    Damon Armstrong, Technology Consultant
    [Blog] [Articles]
  •  09-24-2008, 4:22 AM Post number 69690 in reply to post number 69672

    Re: Mysteries of the NET Framework: Question 4

    In UI apps, I've always found it's handy to push anything that might possibly take a long time off on to something that isn't the UI thread - it helps avoid the dreaded "Not Responding" status, and means your app keeps getting repainted and so on.

    There's nothing more irritating than accidentally typing in a non-existant hostname or something, only to have the entire UI lock up on you for ten seconds while it waits for the DNS query to time out!

    Does make keeping things consistent a bit trickier though...

    Robert Chipperfield
    Developer
    Red Gate Software Ltd
  •  09-29-2008, 10:17 AM Post number 69757 in reply to post number 69690

    Re: Mysteries of the NET Framework: Question 4

    Rob, have you used multiple threads to do UI?

    If so why have you done this and what benefits does it have?

    Also what are the pitfals?

    David

  •  09-29-2008, 11:33 AM Post number 69758 in reply to post number 69757

    Re: Mysteries of the NET Framework: Question 4

    The benefits can be huge - especially on things like DNS queries that potentially take several seconds to time out. It also means you can provide progress indication to users, like the green "spinney" graphics that we tend to use a lot in Red Gate products, rather than leaving them wondering if the application has frozen or not.

    One of the biggest source of crashes I've had in the past is where you spin something off into another thread, then the form gets closed before the operation completes. When it does, the control has been disposed, and so you get a crash.

    Hence the almost ubiquitous bit of code before invoking on a control of checking if it's null, checking its Disposing and IsDisposed properties are both false, and check its HandleCreated is true.

    Robert Chipperfield
    Developer
    Red Gate Software Ltd
  •  09-30-2008, 8:35 AM Post number 69774 in reply to post number 69758

    Re: Mysteries of the NET Framework: Question 4

    In ASP.NET, you can choose to handle requests "asynchronously", which means request processing is split in two. The first half runs on one thread, from which you launch some expensive I/O bound operation such as a database query, then cede control and return the I/O operation's IAsyncResult back to the ASP.NET framework. Later, when the IAsyncResult signals completion, the framework takes another thread from its threadpool and calls your page to do its second half of processing and render an HTML page.

    The whole idea of this is to reduce the number of threads that are sitting around waiting for I/O to complete.

  •  09-30-2008, 9:52 AM Post number 69775 in reply to post number 69758

    Re: Mysteries of the NET Framework: Question 4

    Rob,

    That's very interesting about checking for NULL, Disposing and IsDisposed

    have you ever been caught out by the order of these calls?

    Also I could see how you can reduce the window of threads calling controls that have been disposed, but can you elimate the problem all together?

    Isn't there some theoretical window?

    Do you like using async. calls between the threads or sync ? Does this impact on performance?

    Regards

    David

     

  •  09-30-2008, 10:13 AM Post number 69778 in reply to post number 69775

    Re: Mysteries of the NET Framework: Question 4

    I'll answer the sync or async bit first; it's a bit easier :-).

    I normally go for a synchronous invoke when going back on to the GUI thread from a worker - it's normally the case that the worker thread is finished once the final GUI update has happened, so it's not too much of a problem to block that. And of course, the GUI update should be fairly quick anyway.

    Aync invokes can be really useful on delegates using the "BeginInvoke" method, but make sure you call "EndInvoke" exactly once for every BeginInvoke, or you'll end up with either an exception (calling it twice) or a possible memory leak, according to Microsoft, if you don't call it at all.

    I normally do "Diposing || IsDisposed || !HandleCreated" - the theory being, if something is in the process of being disposed, it's going to go through the "Disposing" step into "IsDisposed", then stay there.

    I'm not sure that you can close the window of vulnerability completely by just using those calls, but it's normally good enough in practice.

    I guess if you wanted to be absolutely bombproof, you could do something like the following:
    - Have a member variable (volatile, of course) that indicates an invoke is about to happen
    - Before checking IsDisposed etc, set it to true
    - Wherever the form is disposed from, check that that member isn't set, and if it is, "deal with it somehow", where "somehow" is a little bit undefined here :-)
    - On the other thread, having entered the Invoke, unset the marker.

    This needs a bit more thought really because you might have two threads both setting the marker, so you'd need to make sure one doesn't unset it when the other is still going, but you get the idea...

    Robert Chipperfield
    Developer
    Red Gate Software Ltd
  •  10-01-2008, 12:44 AM Post number 69790 in reply to post number 69672

    Re: Mysteries of the NET Framework: Question 4

    In my job I do a lot of math - multiple threads are essential in large calculations that can be parallelized, particularly when you are running on a multiproc system. 

    elsasoft.org
  •  10-01-2008, 6:20 AM Post number 69799 in reply to post number 69672

    Re: Mysteries of the NET Framework: Question 4

    When work can be done independently from another and the performance overhead of context switching is lower than the expected profit of doing it parallel
  •  10-01-2008, 7:29 PM Post number 69821 in reply to post number 69672

    Re: Mysteries of the NET Framework: Question 4

    Multithreading is preferable when you have a large amount of work to be done in a background process that does not depend on being completed sequentially.

  •  10-05-2008, 7:04 PM Post number 69925 in reply to post number 69672

    • mrhassell is not online. Last active: 15-10-2008, 3:55 AM mrhassell
    • Top 200 Contributor
    • Joined on 10-06-2008
    • Melbourne, Australia
    • Level 1: Deep thought

    Re: Mysteries of the NET Framework: Question 4

    Shared resources are the primary way of introducing threads in a relative fashion. As mentioned also services (which typically are dependant on multiple levels of shared resources) can benefit greatly from multi-threading.

    A simple example is the "Cache" method where an item has been added to a data collection and is not yet contained within the global cache collection.

    Rebuilding a new cache to include the added object/s, using a tear down method would introduce local Mutex threads, which would require a release of the thread Mutex.
  •  10-15-2008, 1:40 PM Post number 70025 in reply to post number 69925

    Re: Mysteries of the NET Framework: Question 4

    I recommend that you try to refrain from explicitly creating threads, and instead rely upon the BeginInvoke, EndInvoke pattern, or utilize the thread pool; however, there are some cases where the BeginInvoke pattern might not be available, or the thread pool might be the best option.

    For example if your building a component you might want to shy away from the threadpool not knowing what process your going to be hosted in or how it will use the thread pool.

    Put that aside the types of activities I'd look at pushing to other threads are:

    • Any call that requires going over the network such as a web service, database etc.
    • Intensive disk activity
    • CPU intensive algorithims which could benefit from leveraging multi-core machines (I'd give the Parallels library from MS a shot before trying to thread an algorithim myself).

    -Josh

  •  10-15-2008, 4:37 PM Post number 70030 in reply to post number 69682

    Re: Mysteries of the NET Framework: Question 4

    Worst. answer. ever. :)
Page 1 of 2 (20 items)   1 2 Next >
View as RSS news feed in XML