Question:
Do you have an example of a standard asynchronous method call with callback in CSharp ?Any event driven asynchronous sample in dot.net ??
Answer:
There are some simple ways to do it, called "fire and forget" (you don't wait for the completion of your method and you get no notification)And then there is a more complex way to call methods asynchronously where you pass your asynchronous method call a callback function that is called on completion.
A typical usage sample
The idea here is, that you have a long running task and want to set it on a different thread. Once the task is completed you want to get a call that allows you to proceed with the results.
internal void Run() { Console.WriteLine("Start Run"); Calculator calc = new Calculator(); calc.FindPrimeCompleted +=new EventHandler<FindPrimeCompletedEventArgs>(calc_FindPrimeCompleted); calc.FindPrimeAsync(4); Console.WriteLine("Finished Run"); Console.ReadLine(); } void calc_FindPrimeCompleted(object sender, FindPrimeCompletedEventArgs e) { int result = e.Result; Console.WriteLine("The result is : " + result); if (e.Error != null) { Console.WriteLine("Error : " + e.Error.Message); } } // here is the arguments definition public class FindPrimeCompletedEventArgs : AsyncCompletedEventArgs { public int Result { get; private set; } public FindPrimeCompletedEventArgs(Exception err, bool cancelled, object userState, int res) : base(err, cancelled, userState) { this.Result = res; } }
To make this work you have to create your worker class, add an event and a asynchronous method.
Follow these steps:
- 1) Create a simple method
- 2) Create an asynchronous method
- 3) Create a delegate instance for your asynch method
- 4) Create a callback instance with your method callback
- 4a) Create a callback function
- 5) Invoke delegate asynchronously
- 6a) Define event
- 6b) Implement event method
Here is an example
public class Calculator { private readonly object _sync = new object(); private bool _busy; // 1) simple method private int FindPrime(int x) { // fake prime search Thread.Sleep(3000); //throw new ApplicationException("Very BAD error"); return x * 11 -1; } // 2) asynchronous method public void FindPrimeAsync(int x) { // 3) create delegate Func<int, int> worker = new Func<int, int>(FindPrime); // 4) create a callback instance with your method callback AsyncCallback completedCallback = new AsyncCallback(FindPrimeCompletedCallback); // AsyncOperation is responsable to marshal the calls to the appropriate thread or context. // you can pass a UserSuppliedState object to uniquely identify your asynchronous operation AsyncOperation async = AsyncOperationManager.CreateOperation(null); // 5) invoke delegate asynchronously, passing the orignial arguemnt(s) x, and then the completedCallback and AsyncOperation manager worker.BeginInvoke(x, completedCallback, async); } // 4a Create a callback function private void FindPrimeCompletedCallback(IAsyncResult ar) { Func<int, int> worker = (Func<int, int>)((AsyncResult)ar).AsyncDelegate; AsyncOperation async = (AsyncOperation)ar.AsyncState; Exception err = null; bool cancelled = false; object userState = null; int res = 0; // finish the asynchronous operation and get result try { res = worker.EndInvoke(ar); } catch (Exception ex) { err = ex; } // raise the completed event FindPrimeCompletedEventArgs completedArgs = new FindPrimeCompletedEventArgs(err, cancelled, userState, res); async.PostOperationCompleted( e => OnFindPrimeCompleted((FindPrimeCompletedEventArgs)e), completedArgs); } // 6b) Implement event method protected virtual void OnFindPrimeCompleted(FindPrimeCompletedEventArgs e) { if (FindPrimeCompleted != null) FindPrimeCompleted(this, e); } // 6a) Define event public event EventHandler<FindPrimeCompletedEventArgs> FindPrimeCompleted; }
No comments:
Post a Comment