Threading question yet again...

Threading question yet again...

Old forum URL: forums.lhotka.net/forums/t/3351.aspx


DCottle posted on Wednesday, August 08, 2007

I have read ALOT of posts about threading and the CSLA framework and I still feel compelled to ask about my little scenerio.

 

First, let me say that we are not using remoting or a seperation of the DataPortal onto another physical machine whatsoever.  the entire BO layer and the GUI will reside on the same machine.

I have notice a significant increase in performance with my limited testnig in simply making the Editable Collections Update method multithreaded.  The very small code sample is below.

Can somebody please comment on the complication I am likely to see using this small enhancment?

(Also, can somebody please comment on how to get your code pasted from Visual Studio with single spaced lines...quite annoying)

Protected Overrides Sub DataPortal_Update()

'Loop through the deleted objects and call their Update methods

For Each obj as CallAllocationPhone In DeletedList

   obj.Update()

Next

'Now clear the deleted objects from the list

DeletedList.Clear()

'Loop through the objects to add and update, calling the Update Method

For Each child As CallAllocationPhone In Me

   Dim newThread As New System.Threading.Thread(AddressOf UpdateChildObject)

   newThread.Start(child)

Next

End Sub

Public Shared Sub UpdateChildObject(ByVal child As Object)

   DirectCast(child, CallAllocationPhone).Update()

End Sub

 

 

RockfordLhotka replied on Wednesday, August 08, 2007

A couple quick observations:

  1. You should probably use the threadpool, not raw threads. For one thing, you'll get reuse of threads, but more importantly you won't get one thread per child. After a certain point you'll seriously harm Windows overall performance by creating hundreds of threads like could happen with a larger list of child objects. Your current technique could create a LOT of threads very rapidly, but the threadpool manages the threads used, reuses them and throttles the work by queuing tasks until a thread is free.
  2. I can't see where this would work with transactions - though I could be wrong. ADO.NET isn't threadsafe though, so your only hope to get transactions might be with TransactionScope or EnterpriseServices, because they might (or might not) be threadsafe. But without transactions, you lack data integrity because of the issues listed below.
  3. You get the illusion of performance, but the real task is probably actually taking longer than before. What's happening here is that the thread running DP_U() returns, but the background tasks are still running.
  4. You never could switch to an app server, at least not without adding some thread syncrhonization code. It is quite realistic to think that the main thread's task will complete while the background threads are still running. If you have an actual app server the server request could end before those background threads are done and you'd lose data because those background threads could terminate.
  5. The same issue as the previous one can happen with a local config like yours too. It is possible for the user to close the app before those background threads complete - again losing data in an unpredicatable manner - because the background threads would terminate.
  6. To solve these last two issues, you need to block the main thread in DP_U() from leaving DP_U() until the background threads are complete. There are a variety of ways to do this, but as with all threading code, it is hard to get it right such that you don't have race conditions or deadlocks.

 

 

Copyright (c) Marimer LLC