views:

1636

answers:

6

I have a dialog based application in which I will delegating the I/O operation read write to different thread.

I just want to clear is there any difference between two approaches..

First approach: ( I am doing this in ,my main form -Form.cs)

delegate void Action();
Action _action = new Action(Method);
this.BeginInvoke(_action);

Second approach:

Thread th = new  Thread( new ThreadStart(_action));
th.Start();

I noticed that BeginInvoke hangs the UI for a second while second approach don't ..

Please help

A: 

the difference would be that the BeginInvoke method simply calls the delegate asynchronously on the SAME thread.

Using the Thread.Start, you'll be creating an entirely different thread.

Thread.Start will definately give you better performance!

Sk93
Better performance is a bit of an assumption... and with a thread you being to run into the old CrossThreadedExceptions...
Pondidum
its an assumption based on a basic test.see a quick test here: http://shevaspace.blogspot.com/2007/08/delegatebegininvoke-vs.htmlbut yes.. there are other factors to take into account, but CrossThreadedExceptions aren't exactly a problem if you're aware of them...
Sk93
+6  A: 

BeginInvokes executes the delegate asynchronously on the UI thread (which is why it hangs the UI), by posting a message to the window. That's what you need to do if the code in the delegate accesses the UI.

The approach with Thread.Start executes the delegates on a new, independant thread.

Thomas Levesque
+7  A: 

BeginInvoke will post the action in the message queue of the message pump on the same thread as the Form, it will not create a new thread.

Control.BeginInvoke behaves similar to an asynchronous thread start, but has important internal differences.

Read in further detail an article here.

kek444
+3  A: 

Thread.Start runs it on your new Thread.

Control.BeginInvoke runs the method on the thread that the Control this belongs to. If you are currently on the thread of the control, the method is not run until you return control to the message loop, e.g. exit your event handler.

Timbo
+1  A: 

Try this.

class Form1: Form
{
   public void ButtonWasClicked(object sender, EventArgs e)
   {
       /* Call the UI's Invoke() method */
       this.Invoke((MethodInvoker)delegate()
       {
           /* Stuff to do.. you can access UI elements too without
            * the nasty "Control accessed from another thread.."
            * Use BeginInvoke() only if you have code after this section
            * that you want the UI to execute without waiting for this 
            * inner blockto finish. 
            */
       }
   }
}

Regarding BeginInvoke(), it is used so the function will return immediately and the next line will be executed and so on and so forth without waiting for the method to finish.

The difference is that if you create a thread you will have more control over it just like any other thread. You will run into CrossThreadExceptions! Whereas if you use IAsyncResult and BeginInvoke(), you will not have control over the execution flow of the asynchronous operation as it's managed by the runtime.

With invocation you can also send more parameters to a method and have a method being called once the operation is finished.

MyDelegateWithTwoParam del = new MyDelegateWithTwoParam(_method);
AsyncCallback callback = new AsyncCallback(_callbackMethod);
IAsyncResult res = del.BeginInvoke(param1, param2, callback, null);

private void _callbackMethod(IAsyncResult iar) {
   /* In this method you can collect data that your operation might have returned.
    * If MyDelegateWithTwoParam has a return type, you can find out here what i was. */
}

I've widely used both for UI development. I would use threads more for service-like objects. (Think of an object that stays and listens for TCP connections) and asynchronous methods for background work behind a UI (have a look at BackgroundWorker too). Don't worry if the first approach took an extra second to start: Thread.Abort() is not always your best solution either. Try _abort flags in your process code and lock it.

Hope I've answered the question.

Leo Bruzzaniti

lb
+1  A: 

As others have posted, Thread.Start will launch a new thread, and Control.BeginInvoke() will run code on the UI thread (necessary if you want to change a field's value, for example).

However, I have found that the simplest technique for executing a background task in WinForms is to use a BackgroundWorker. You drop it onto a form, wire up the events, and call RunWorkerAsync(). Then you write your background task in the DoWork event. Any UI refresh can be put in the RunWorkerCompleted event.

Using a BackgroundWorker avoids all the annoying thread handling and IsInvokeRequired stuff.

Here's a more detailed how-to article.

Don Kirkby