We can call a method asynchronously by using beginInvoke and endInvoke methods of delegate,
we pass method's parameters to beginInvoke method then we have got to pass return value of beginInvoke method to endInvoke method, endInvoke method returns actual result(return type of method).
Asynchronous call to a method runs method in a separate thread.
Once you ask the framework to call something asynchronously, it needs a thread to do the work. It can not be the current thread, because that would make the invocation synchronous (blocking). Instead, the runtime queues a request to execute the function on a thread from the .NET Thread Pool. You don’t really need to code anything for it, all of it happens in the background. But, just because it is all transparent doesn’t mean you should care about it. There are a few things to remember:
Once you ask the framework to call something asynchronously, it needs a thread to do the work. It can not be the current thread, because that would make the invocation synchronous (blocking). Instead, the runtime queues a request to execute the function on a thread from the .NET Thread Pool. You don’t really need to code anything for it, all of it happens in the background. But, just because it is all transparent doesn’t mean you should care about it. There are a few things to remember:
- FlushToDisk is executed on a separate thread, a thread that belongs to the .NET Thread Pool.
- A .NET Thread Pool normally has 25 threads in it (you can change that limit), and each time FlushToDisk is called, it is going to be executed on one of these threads. You can't control which one.
- The Thread Pool has its limits! Once all the threads are used, an async method invocation is queued until one of the threads from the pool is freed. This is called Thread Pool Starvation, and normally when it comes to that, performance is compromised.
class DataCache {
public int FlushToDisk(string fileName) {
// simulate a long operation
Thread.Sleep(4000);
return 0;
}
}
class Program {
// define a delegate for the long operation
delegate int CacheFlusher(string fileName);
static void Main(string[] args) {
// create the object and then the delegate
DataCache cache = new DataCache();
CacheFlusher flusher = new CacheFlusher(cache.FlushToDisk);
// invoke the method asynchronously
IAsyncResult result = flusher.BeginInvoke("data.dat", null, null);
// get the result of that asynchronous operation
int retValue = flusher.EndInvoke(result);
Console.WriteLine(retValue);
}
}
Method # 01
// begin execution asynchronously
IAsyncResult result = flusher.BeginInvoke("data.dat", null, null);
// wait for it to complete
while (result.IsCompleted == false) {
// do some work
Thread.Sleep(10);
}
// get the return value
int returnValue = flusher.EndInvoke(result);
Method # 02
// call the delegate asynchronously
IAsyncResult result =
flusher.BeginInvoke("data.dat", null, null);
// wait for the call to finish
result.AsyncWaitHandle.WaitOne();
// get the return value
int returnValue = flusher.EndInvoke(result);
Method # 03
static void Main(string[] args) {
// create the object
DataCache cache = new DataCache();
// create the delegate
CacheFlusher flusher = new CacheFlusher(cache.FlushToDisk);
// call the delegate asynchronously
flusher.BeginInvoke("data.dat", new AsyncCallback(CallbackMethod), flusher);
// wait to exit
Console.WriteLine("Press enter to exit");
Console.ReadLine();
}
static void CallbackMethod(IAsyncResult result) {
// get the delegate that was used to call that
// method
CacheFlusher flusher =
(CacheFlusher) result.AsyncState;
// get the return value from that method call
int returnValue = flusher.EndInvoke(result);
Console.WriteLine("The result was " + returnValue);
}
No comments:
Post a Comment