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