tags:

views:

116

answers:

4

I want to call asynchronous methods, but I don't want use a timer. How can I substitute the timer? I need the invoker that substitute the timer.

+1  A: 

You don't need a timer to invoke asynchronous methods... There are numerous other mechanisms availble to do that. A timer is used to invoke something at a specific time, or recurrently on some specific interval. Which is your requirement, to call something asynchronously, or to call something at specific time(s) ??

Charles Bretana
My requirements is to call asynchronously at specific time(s). I have 5 methods that need to call. If I will use the timer then I must use 5 of it.
Wilson
A: 

Take a look at the following link. I think it has just the answer to your question.

Building MultiThreaded Applications

O. Askari
+5  A: 

You should look into the .NET Asynchronous Programming Model. It's much simpler then it sounds. You simply create a delegate to a method that you want to run asynchronously. Then call BeginInvoke on the delegate and your method is automatically run on a background thread.

In the asynchronous method, if you need to update the UI, you must use Control.Invoke/BeginInvoke on the relevant form or control.

Also, if the asynchronous method needs to return some result to the UI thread, you will need to utilise the IAsyncResult (returned from BeginInvoke) and the EndInvoke method.

See the article Calling Synchronous Methods Asynchronously for more details.

On the other hand, if you're just looking for an equivalent to the javascript method window.settimeout() in Windows.Forms the following avoids threads entirely by wrapping the standard Timer in a re-usable method:

public void SetTimeout(EventHandler doWork, int delayMS)
{

    System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

    timer.Interval = delayMS; 

    timer.Tick += delegate(object s, EventArgs args) { timer.Stop(); };

    timer.Tick += doWork;

    timer.Start();

}

then to call it:

    SetTimeout(delegate { YourMethod(); }, 100);

Just like the Timer you drag onto a form, YourMethod() is run on the UI thread by the form message loop. Therefore you do not need to worry about BeginInvoke/Invoke at all.

Ash
@Serge, you're getting Control.BeginInvoke and Delegate.BeginInvoke confused. Control.BeginInvoke runs on the main UI thread but the Delegate verion definitely runs on a worker/background thread. Read the linked article for more information.
Ash
Ash, I stand corrected. I removed the offending comment.
Serge - appTranslator
A: 

Control.BeginInvoke() is your friend if your app has a GUI. You give it a delegate to your function and .NET will call after the current event handler finished executing.

NB: As opposed to Delegate.BeginInvoke(), Control.BeginInvoke() executes in the main thread (actually the thread where the control was created).

In most cases, I personally prefer a deffered execution in the same thread to an async execution in a worker thread: Much less possible side effects. Your mileage may vary.

void f(string s)
{
  Debug.WriteLine(s + " -> Thread = " + 
    System.Threading.Thread.CurrentThread.Name);
}

private void button_Click(object sender, EventArgs e)
{
  Debug.WriteLine("Start button_Click");
  f("straight call in button_Click");
  BeginInvoke(new Action<string>(f), "async call through BeginInvoke()");
  Debug.WriteLine("End button_Click");
}

Output:

Start button_Click
straight call in button_Click -> Thread = Main Thread
End button_Click
async call through BeginInvoke() -> Thread = Main Thread

Note: the name "Main Thread" is assigned to the thread in the Main() of the program.

Serge - appTranslator
@Serge, you're confusing Control.BeginInvoke with Delegate.BeginInvoke. Your example is actually executing this.BeginInvoke() where 'this' is your form. Form inherits from Control. So your use of BeginInvoke (or invoke) is pointless. Control.BeginInvoke() is mainly useful when called from a background/worker thread. .NET provides the APM (see my answer) so that any delegate you define has a BeginInvoke()/Invoke() method that can be used to call a method on a background/worker thread. See CLR Via C# by Jeff Richter for a great coverage of this in a book.
Ash
Ash, thanks for correcting me. And apologies also! I have no excuses: 10k people usually don't make such basic mistakes + the book is on my bookshelf! I edited my answer to reflect your comment
Serge - appTranslator
@Serge, My pleasure. Hope I didn't come across as a "know it all", Believe me, I've learned so much on StackOverflow too. I didn't understand Delegates very well until I actually wrote some test code and read had CLR Via C# beside me. There's no magic about being a 10K+ person, I've only been one for 2 weeks ;)
Ash