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 ...
随机推荐
- sparkr跑通函数 包含排序
spark1.4.0的sparkR的思路:用Spark从大数据集中抽取小数据(sparkR的DataFrame),然后到R里分析(DataFrame). 这两个DataFrame是不同的,前者是分布式 ...
- 层层递进——宽度优先搜索(BFS)
问题引入 我们接着上次“解救小哈”的问题继续探索,不过这次是用宽度优先搜索(BFS). 注:问题来源可以点击这里 http://www.cnblogs.com/OctoptusLian/p/74296 ...
- Prolog学习:数独和八皇后问题
上一篇简单介绍了下Prolog的一些基本概念,今天我们来利用这些基本概念解决两个问题:数独和八皇后问题. 数独 数独是一个很经典的游戏: 玩家需要根据n×n盘面上的已知数字,推理出所有剩余空格的数字, ...
- Maven POM
POM代表项目对象模型.它是 Maven 中工作的基本单位,这是一个 XML 文件.它始终保存在该项目基本目录中的 pom.xml 文件.POM 包含的项目是使用 Maven 来构建的,它用来包含各种 ...
- 使用ConcurrentLinkedQueue惨痛的教训【转】
转自:http://blog.csdn.net/jackpk/article/details/49634577 服务端原本有个定时任务对一个集合ArrayList 中的消息做处理. 因为考虑到处理消息 ...
- Win7-64位安装TensorFlow-GPU
1.查看电脑显卡 路径:计算机--属性--设备管理器-显示适配器 2.显卡(GPU)是否支持CUDN https://developer.nvidia.com/cuda-gpus 3.安装 1)CUD ...
- Business vs Technology
Business 只是 Technology的子集. Business只是体现在Code中. 比如说是HTML页面中内容的一部分. 或者说业务是对HTML组成的内容的分类. 比如说Smallbusin ...
- Objective-C语法之扩展(Extension)的使用
Objective-C 2.0增加了Class Extension用于解决两个问题: 可声明私有可读写的属性,而在类的声明中是同名的公开只读属性,从而来支持公开只读.私有可读写的属性 可声明私有方法: ...
- (第3篇)HDFS是什么?HDFS适合做什么?我们应该怎样操作HDFS系统?
摘要: 这篇文章会详细介绍HDFS是什么,HDFS的作用,适合和不适合的场景,我们该如何操作HDFS? HDFS文件系统 Hadoop 附带了一个名为 HDFS(Hadoop分布式文件系统)的分布 ...
- windows 下查看端口占用情况
windows下面查看端口占用情况: netstat -ano|findstr "8888" TCP 127.0.0.1:8888 0.0.0.0:0 LISTENING 6876 ...