locked
how to call a method asynchronously RRS feed

  • Question

  • hi,
    i have to call few methods in asynchronous way.

    here is my requirement.
    1.all methods will be in main class.
    2.each method has different parameters.

    things i dont want to do...
    it is possible to combine all those method in a "class" and then use a "thread".but i dont want to do it this way
    its possible to use "BeginInvoke" but it requires lot of delegate declaration as each method has "different parameter".

    im confused how to do it.
    can anyone help me...
    thanks in advance.


    bals
    Wednesday, July 22, 2009 4:51 PM

Answers

All replies

  • Unfortunately, you've just described two of the most common ways to call methods asynchronously.  The third one would be BackgroundWorker, which will work in a Windows Forms application.  If you're writing a console app, however, you've just listed the only two options, and you'll have to use one of them.
    David Morton - http://blog.davemorton.net/ - @davidmmorton - ForumsBrowser, a WPF MSDN Forums Client
    Wednesday, July 22, 2009 4:53 PM
  • hi David,
    thanks for ur reply..
    and my application is a windows service, and isnt there a better way use threading ?
    bals
    Wednesday, July 22, 2009 5:01 PM
  • hi David,
    thanks for ur reply..
    and my application is a windows service, and isnt there a better way use threading ?
    bals

    No.
    David Morton - http://blog.davemorton.net/ - @davidmmorton - ForumsBrowser, a WPF MSDN Forums Client
    Wednesday, July 22, 2009 5:01 PM
  • David is right... you will have to do it using one of those two options. Anyhow, I personally like the async pattern that abstracts delegation by creating 2 methods: MyMethod, MyMethodAsync. You can either make it fire and forget or with a proper callback as a parameter. Still, this only abstracts the thread creation or delegation with BeginInvoke, but you'll need to implement it using either of them.

    Regards,
    Fernando.
    I always try to Keep it Sharp & simple.
    Wednesday, July 22, 2009 5:19 PM
  • thanks fernando,
    i wud prefer creating a seperate class and then put all methods in it and then call it using thread from main class.
    its quite hectic... but i hv no other option :)
    .. thanks again fernando
    bals
    Wednesday, July 22, 2009 5:36 PM
  • First off, using a thread to call just a single method is *really* inefficient.  More to the point, there is no reason at all to have to put the methods you want to call in the thread in a separate class.  Why do you think you do?

    Hans Passant.
    Wednesday, July 22, 2009 6:05 PM
  • I surmise that when you say asynchronous; that really means to call the method in a background fashion?

    If that is the case and I am not off track, why not use anonymous delegates with thread pool class and have the result of the operation placed on a queue for later pickup. I provide such an example on my blog entitled: C# MultiThreading Using ThreadPool, Anonymous Delegates and Locks . HTH GL
    William Wegerson (www.OmegaCoder.Com)
    • Marked as answer by Ulab_newbie Thursday, July 23, 2009 9:37 AM
    Wednesday, July 22, 2009 6:21 PM
  • I thought I'd offer something completely radical as a solution.  Another (albeit complicated) option is to follow the BeginInvoke pattern, but don't actually use threads, but it requires a serious departure from imperative code, and requires code to be divided up into atomic units of work that can execute free from dependencies on other code.

    For example, instead of c = Add( a, b ), The asynchronous version of the method does this:

    AsyncAdd( a, b, out c );

    The problem is knowing when the operation has completed.  So usually there is a handle of some kind associated with the operation.
    asyncOperation = AsyncAdd( a, b, out c );

    then someone can check to see if the operation is complete e.g.:  if( asyncOperation.Complete ) ...

    But the nasty part is being able to write "script" within the language where you use language flow control constructs to "wait" for things to happen, and to cause things to happen in order.

    Like this:

    Before();
    asyncOperation.WaitForCompletion();
    After();


    To implement this, you would have to somehow preserve your running state, and allow your dispatcher to complete the scheduled asynchronous addition calculation, then resume flow after the WaitForCompletion() call so that the After() call can execute.  We had SetJmp / LongJmp in C++ for things like this.  We could also use threads.  The point is that if you want to WAIT for an asynchronous operation, you have committed to having two call stacks (and most likely two threads, or some kind of co-routine implementation) and that is a big pain to manage.

    So using TWO threads is fine, one that invokes script and another that completes async operations.  If async operations can wait, then you'll need yet another thread for the ones that do.  Except that using threads is TOO easy, because you can interrupt execution anywhere, and you often end up writing critical sections and things like that to ensure thread safety.

    If you decided to implement a solution yourself, you could implement it all with one thread provided that you do not rely on the call-stack for flow control.  It means that your asynchronous code never waits or blocks depending on the result of an asynchronous operation.  Instead, you schedule atomic bits of code to run, and describe the dependencies on order of execution to your dispatcher declaratively.

    One way to do this is to declare actions with dependencies, and you only execute something after the dependent actions have completed.

    I once wrote an entire game and the only dispatching call I wrote was something called "ExecuteAfter" that executed something after something else happened.  It turned out to be the only method I ever needed to script the entire game.

    This function would take a delegate and a list of actions to wait for before executing.

    Imagine something like this:

    var work1 = ExecuteAfter( action: delegate { A(); } );
    var work2 = ExecuteAfter( action: delegate { B(); }, after: work1 );
    var work3 = ExecuteAfter( action: delegate { C(); }, after: work2 );


    The dispatcher will simply not execute an action until all of its dependent actions have completed.  All actions are forbidden to block.  Anything you want to do after something else must be dispatched using another ExecuteAfter call.  Obviously the dispatcher would keep a list of actions and their dependencies.  This serves the same purpose as having multiple call stacks for multiple threads.  Somebody has to invoke the Dispatcher once, after there is at least one thing in the dispatcher's list of things to do. 

    It also is a good paradigm for describing parallel actions, and it's scalable for use with many processors in a good way.


    Finally, my point is that hopefully, if you've read this far, you'll see that just using multiple threads or the BeginInvoke technique is going to be far easier!  ;)

    • Edited by Wyck Wednesday, July 22, 2009 8:01 PM typo
    Wednesday, July 22, 2009 8:00 PM
  • In ye olden days of single core processors, I called methods quasi-asychronously using a timer.  Is there a .NET construct that emulates this pattern?

    internal static class Module1
        {
          private static Timer Tmr = new Timer();
          private static int TmrState;
          private static object TmrData;
          public static void Main()
          {
            Tmr.Elapsed += Tmr_Elapsed;
            Tmr.Interval = 1;
            Tmr.Start();
            Console.ReadLine();
          }
          public static void Tmr_Elapsed(object sender, ElapsedEventArgs e)
          {
            Tmr.Stop();
            switch (TmrState)
            {
              case 0:
                TmrState = 1;
                TmrData = "This is data for Method2.";
                Tmr.Start();
                Method1();
                break;
              case 1:
                TmrState = 2;
                if (((string)TmrData) == "This is data for Method2.") Tmr.Start();
                Method2((string)TmrData);
                break;
              case 2:
                TmrState = 3;
                TmrData = Method3();
                Tmr.Start();
                break;
              case 3:
                TmrState = 4;
                TmrData = Method4((string)TmrData);
                Tmr.Start();
                break;
              case 4:
                TmrState = 1;
                Tmr.Start();
                Method1();
                break;
            }
          }
        }
        public static void Method1()
        {
          Console.WriteLine("This was Method1");
        }
        public static void Method2(string S)
        {
          Console.WriteLine("This was Method2 with " + S);
        }
        public static string Method3()
        {
          Console.WriteLine("This was Method3");
          return "This was Method3";
        }
        public static string Method4(string S)
        {
          Console.WriteLine("This was Method4 with " + S);
          return "This was Method4";
        }
      }
    }
    Wednesday, July 22, 2009 9:44 PM
  • thanks OmegaMan,
    the idea of Anonymous Delegate is cool and i almost done with that.
    its also easy to call any method of different parameters without defining a delegate first itself..
    and ur blog is really usefull.

    thanks once again.!!

    • Edited by Ulab_newbie Thursday, July 23, 2009 9:52 AM
    Thursday, July 23, 2009 9:40 AM