Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / WinForm General / June 2006

Tip: Looking for answers? Try searching our database.

Threading Advice Quick Question

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Mark - 29 Jun 2006 09:42 GMT
Hi I have a non UI set of classes which do bits and pieces like getting
file lists, generating xml etc. I figured on doing some of these
processes on seperate threads. These wouldnt be called by the UI they
would be controlled by the objects themselves. My question is simply
whats the correct way to notify completion back to the object that
called it. I have used control.invoke in the past but the objects arent
controls as such although I could make them I guess. Just looking for
some advice on best practice.

Cheers
Mehdi - 29 Jun 2006 10:30 GMT
> Hi I have a non UI set of classes which do bits and pieces like getting
> file lists, generating xml etc. I figured on doing some of these
[quoted text clipped - 4 lines]
> controls as such although I could make them I guess. Just looking for
> some advice on best practice.

If your classes are general non-UI classes that performs asyncronous
operations (let's call these classes the business layer) and notify the
client of their completion via callback methods  then the clients of these
classes should expect these callbacks to be called in a worker thread and
take appropriate steps to deal with it. This is how all the classes in the
.NET Framework that provide asyncronous methods do it (they have BeginXXX
methods that take an AsyncCallback delegate and they invoke the callback
method in a thread from the thread pool). In other words, it is in your UI
layer that you should marchall the callback method to the UI thread if you
need to access any UI control. Your business layer does not have any
knowledge of the constraints of the UI when it comes to multi-threading and
should not bother about it.

Now, if you really want to interleave the UI and the business layers, you
could pass a Control object in the constructor of your business classes
allowing them to call Invoke() or BeginInvoke() on it in order to invoke
their callback methods in the UI thread.
Alexander Ubillus - 29 Jun 2006 18:02 GMT
Hi Mehdi,

You can do this by using a Delegate, just invoke the delegate after
finishing the work.
The method pointed to by the delegate can be in the same class where you do
the work.

Hope this helps.

>> Hi I have a non UI set of classes which do bits and pieces like getting
>> file lists, generating xml etc. I figured on doing some of these
[quoted text clipped - 23 lines]
> allowing them to call Invoke() or BeginInvoke() on it in order to invoke
> their callback methods in the UI thread.
MuZZy - 30 Jun 2006 05:05 GMT
> Hi I have a non UI set of classes which do bits and pieces like getting
> file lists, generating xml etc. I figured on doing some of these
[quoted text clipped - 6 lines]
>
> Cheers

Here's the thread class i wrote to support callback. Its imple and esay
to extend if needed:

namespace MySystem
{
    public delegate void MyThreadStart();
    public class MyThread
    {
        public event EventHandler ThreadFinished;
        protected MyThreadStart m_tsThreadStart;
        public MyThread(MyThreadStart tsThreadStart)
        {
            m_tsThreadStart = tsThreadStart;
        }

        public void Start()
        {
            m_tsThreadStart.BeginInvoke(new AsyncCallback(CallBack), null);
        }

        private void CallBack(IAsyncResult res)
        {
            if (ThreadFinished != null)
                ThreadFinished(this, EventArgs.Empty);
        }
    }
}

And when you create that thread object you just subscribe to its
ThreadFinished event which will fire when the thread is done.

One note: maybe i'm mistaken but i think that callback will fire in
context of that worker thread - just something to be aware of especially
if you deal with UI.

Hope it helps,
MuZZy
Mehdi - 30 Jun 2006 11:24 GMT
> Here's the thread class i wrote to support callback. Its imple and esay
> to extend if needed:
[...]
>     public delegate void MyThreadStart();
>     public class MyThread
>     {
>         protected MyThreadStart m_tsThreadStart;
[...]
>         public void Start()
>         {
>             m_tsThreadStart.BeginInvoke(new AsyncCallback(CallBack), null);
>         }
[...]
>     }

> And when you create that thread object you just subscribe to its
> ThreadFinished event which will fire when the thread is done.

There's like a problem with your helper class. Typically, when somebody
wants to create their own thread instead of using a thread from the
ThreadPool (which is much more efficient), this is because they want to do
some long running operation. Doing a long running operation in a thread
taken from the ThreadPool is a no-no as you might end up starving the
ThreadPool. Yet, that's what you are doing in your class:

m_tsThreadStart.BeginInvoke(new AsyncCallback(CallBack), null);

Calling BeginInvoke() on a delegate doesn't create a new thread but causes
the fonction represented by the delegate to be executed in a thread from
the ThreadPool. This wouldn't be a problem if you made it clear that your
Start() method actually invoked the supplied delegate in a thread from the
ThreadPool and *not* from a new thread. But instead, you have given your
class the very misleading name "MyThread" which leads users to think that
this is just a wrapper for the Thread class; the name of its event
("ThreadFinished") adds to the confusion. I think that you should either
create a new thread in your Start() method instead of using the ThreadPool
or rename your class and make it very clear in the doc and explanation that
your class uses the ThreadPool to invoke to supplied delegate.
William Sullivan - 30 Jun 2006 15:36 GMT
Easiest way to do this is to wrap your current calculation or data-bound
methods with a delegate.  Call BeginInvoke on the delegate and pass a
delegate to a method that will be called upon completion of the asynchronous
method.  In this method, call EndInvoke to retrieve the results of the async
op.  I wrote a little article for CodeProject about it:

http://www.codeproject.com/useritems/Async_Ops_and_Delegates.asp

Check out the code for the third rendezvous technique.  It shows you how to
handle EndInvoke properly.  I'd also suggest you get 'CLR Via C#', which has
lots of good info about asynchronous ops and the various pitfalls you face
when using them.

> Hi I have a non UI set of classes which do bits and pieces like getting
> file lists, generating xml etc. I figured on doing some of these
[quoted text clipped - 6 lines]
>
> Cheers

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.