Explaining Delegates in C# - Part 5 (Asynchronous Callback - Way 2)
In this part of making asynchronous programming with delegates, we will talk about a different way, which is a little better than Way 1. In the previous post, it was like a husband telling his wife...
You know honey, I have a lot of work to do. Why don't you help me up by doing something that you can do pretty well
. In the meantime, I will take care of some other stuff. As soon as I am done, I promise I will pick you up.
Notice that, although it looks like a good way of getting the work done, it has a tiny flaw (not really a flaw, but I will still call it a flaw to make my story!). What if their 6 year old kid called the husband in the meantime? Would the husband appreciate it while waiting he can do nothing else but wait? I mean, what if he has to just pick up the phone and tell his child, you know kiddo, I am here at the mall waiting for your mom. I'll be back in some time! This example just does that. Basically, we know that EndInvoke is a blocking call. If you make this call, you can do nothing but wait, which may make your UI look awful. In this example, we will be waiting for the async call to complete, but still be free enough to do some stuff.
Okay, enough said... let's take a look at the code (in fact, it is always better to run it!!!)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics; namespace EventAndDelegateDemo
{
//The delegate must have the same signature as the method. In this case,
//we will make it same as TortoiseMethod
public delegate string TortoiseCaller(int seconds, out int threadId); public class TortoiseClass
{
// The method to be executed asynchronously.
public string TortoiseMethod(int seconds, out int threadId)
{
Console.WriteLine("The slow method... executes...on thread {0}", Thread.CurrentThread.ManagedThreadId);
for (int i = ; i < ; i++)
{
Thread.Sleep(seconds / * );
Console.WriteLine("The async task is going on thread # {0}", Thread.CurrentThread.ManagedThreadId);
}
threadId = Thread.CurrentThread.ManagedThreadId;
return String.Format("I worked in my sleep for {0} seconds", seconds.ToString());
}
} //Now, that we are done with the declaration part, let's proceed to
//consume the classes and see it in action
//The algorithm would be very simple...
// 1. Call delegate's BeginInvoke
// 2. Do some work on the main thread
// 3. Call the result's AsyncWaitHandle.WaitOne() which would be a blocking call
// 4. Call EndInvoke which won't be a blocking call this time!
// 5. Close the result's AsyncWaitHandle, explicitly.
public class TortoiseConsumer
{
static void Main()
{
//Instantiate a new TortoiseClass
TortoiseClass tc = new TortoiseClass();
//Let's create the delegate now
TortoiseCaller caller = new TortoiseCaller(tc.TortoiseMethod);
//The asynchronous method puts the thread id here
int threadId;
//Make the async call. Notice that this thread continues to run after making this call
Console.WriteLine("Before making the Async call... Thread ID = {0}", Thread.CurrentThread.ManagedThreadId);
IAsyncResult result = caller.BeginInvoke(, out threadId, null, null);
//After calling the method asynchronously, the main thread continues to work...
Console.WriteLine("After making the Async call... Thread ID = {0}", Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Perform more work as the other thread works...");
for (int i = ; i > ; i--)
{
Thread.Sleep();
Console.WriteLine("{0}...", i);
}
Stopwatch s = new Stopwatch();
//Calling WaitOne is a blocking call. As soon as you call WaitOne, you won't proceed further
//in this main thread until the Async call completes
Console.WriteLine("Before calling WaitOne... {0} milliseconds", s.ElapsedMilliseconds.ToString());
s.Start();
//The next call can be a blocking call (in our case it WILL be a blocking call since the Tortoise
//method takes 30 seconds to complete. By now, already 12 seconds are over!
result.AsyncWaitHandle.WaitOne();
//The good thing is that, now you can do update the client while still waiting for the call to complete
Console.WriteLine("Well, I know waiting could be boring, but at the moment I am still waiting...");
//Waiting for 5 seconds now!
result.AsyncWaitHandle.WaitOne();
//Updating once again...
Console.WriteLine("Argghh... when will this end??");
//Waiting till the async call is complete (Notice that this can be blocking!!)
result.AsyncWaitHandle.WaitOne();
s.Stop();
Console.WriteLine("After calling WaitOne... {0} milliseconds", s.ElapsedMilliseconds.ToString());
//Notice that this call will NOT be a blocking call as it was in our previous example!
string returnValue = caller.EndInvoke(out threadId, result);
//Close the wait handle. This is important, since it is not automatically cleared.
//Only the next GC can collect this native handle. So, it is a good practise to clear
//this handle as soon as you are done with it.
result.AsyncWaitHandle.Close();
Console.WriteLine("The call got executed on thread {0}", threadId);
Console.WriteLine("The value returned was - {0}", returnValue);
}
}
}
I will discuss about more ways of doing asynchronous programming in some of my next posts.
Explaining Delegates in C# - Part 5 (Asynchronous Callback - Way 2)的更多相关文章
- Explaining Delegates in C# - Part 6 (Asynchronous Callback - Way 3)
By now, I have shown the following usages of delegates... Callback and Multicast delegatesEventsOne ...
- Explaining Delegates in C# - Part 7 (Asynchronous Callback - Way 4)
This is the final part of the series that started with... Callback and Multicast delegatesOne more E ...
- Explaining Delegates in C# - Part 4 (Asynchronous Callback - Way 1)
So far, I have discussed about Callback, Multicast delegates, Events using delegates, and yet anothe ...
- Synchronous/Asynchronous:任务的同步异步,以及asynchronous callback异步回调
两个线程执行任务有同步和异步之分,看了Quora上的一些问答有了更深的认识. When you execute something synchronously, you wait for it to ...
- Explaining Delegates in C# - Part 1 (Callback and Multicast delegates)
I hear a lot of confusion around Delegates in C#, and today I am going to give it shot of explaining ...
- Explaining Delegates in C# - Part 2 (Events 1)
In my previous post, I spoke about a few very basic and simple reasons of using delegates - primaril ...
- Explaining Delegates in C# - Part 3 (Events 2)
I was thinking that the previous post on Events and Delegates was quite self-explanatory. A couple o ...
- [TypeScript] Simplify asynchronous callback functions using async/await
Learn how to write a promise based delay function and then use it in async await to see how much it ...
- Delegates and Events
People often find it difficult to see the difference between events and delegates. C# doesn't help m ...
随机推荐
- WPF Tutorial - Using A Visual Collection
While WPF and XAML make the common 90% of UI programming quite easy, sometimes it gets a little odd ...
- 自然语言交流系统 phxnet团队 创新实训 个人博客 (十)
下载emacs-23.1.tar.gz http://ftp.gnu.org/pub/gnu/emacs/emacs-23.1.tar.gz cd /opt //cp emacs-23.1.ta ...
- 关于Unity中的旋涡特效的制作(捕鱼达人3技术)(专题八)
Mesh--材质--Shader 1: Mesh 是网格,包括顶点,法线,纹理坐标,切线,三角形.在每一个3D模型节点里面,有一个Mesh Filter组件来提取模型里面的网格数据;2: Shader ...
- QMDP-Net: Deep Learning for Planning under Partial Observability
一篇用deep neural network做POMDP的论文
- 【转】【Centos】Centos下用upstart管理自己的服务程序
Upstart是Ubuntu用来进行服务进程管理的服务,本文介绍如何利用upstart来通过Centos操作系统管理我们自己开发的应用程序. 什么时候要管理我们的应用程序?当我们开发出服务类的应用程序 ...
- Java如何重置正则表达式的模式?
在Java编程中,如何重置正则表达式的模式? 以下示例演示如何使用Pattern类Pattern.compile()方法和Matcher类的m.find()方法来重置正则表达式的模式. package ...
- e809. 在菜单中使菜单项分开
A separator typically appears as a horizontal line. It is used to group related sets of menu items i ...
- 【翻译自mos文章】Linux的/var/log/messages是空的(0k),messages.0, messages.1也是空的
Linux的/var/log/messages是空的(0k),messages.0, messages.1也是空的 来源于: The /var/log/messages is empty, and s ...
- hdu 2771(uva 12171) Sculpture bfs+离散化
题意: 给出一些边平行于坐标轴的长方体,这些长方体可能相交.也可能相互嵌套.这些长方体形成了一个雕塑,求这个雕塑的整体积和表面积. 题解: 最easy想到直接进行bfs或者dfs统计,但此题的麻烦之处 ...
- SpringBoot学习:使用spring-boot-devtools进行热部署
项目下载地址:http://download.csdn.net/detail/aqsunkai/9805821 pom.xml添加依赖: <!--支持热启动jar包--> <depe ...