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.

转:http://www.dotnetscraps.com/dotnetscraps/post/Explaining-Delegates-in-C-Part-5-(Asynchronous-Callback-Way-2).aspx

Explaining Delegates in C# - Part 5 (Asynchronous Callback - Way 2)的更多相关文章

  1. Explaining Delegates in C# - Part 6 (Asynchronous Callback - Way 3)

    By now, I have shown the following usages of delegates... Callback and Multicast delegatesEventsOne ...

  2. 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 ...

  3. 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 ...

  4. Synchronous/Asynchronous:任务的同步异步,以及asynchronous callback异步回调

    两个线程执行任务有同步和异步之分,看了Quora上的一些问答有了更深的认识. When you execute something synchronously, you wait for it to ...

  5. 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 ...

  6. 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 ...

  7. 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 ...

  8. [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 ...

  9. Delegates and Events

    People often find it difficult to see the difference between events and delegates. C# doesn't help m ...

随机推荐

  1. Netty实践

    Netty是JBOSS针对网络开发的一套应用框架,它也是在NIO的基础上发展起来的.netty基于异步的事件驱动,具有高性能.高扩展性等特性,它提供了统一的底层协议接口,使得开发者从底层的网络协议(比 ...

  2. Java容器有哪些?

    网易面试: 问:Java容器有哪些,你聊一聊吧 Java容器: 数组,String,java.util下的集合容器 数组长度限制为 Integer.Integer.MAX_VALUE; String的 ...

  3. Android---如何返回上一Activity

    Android 代码用来返回上一个activity 调用onKeyDown()时发生java.lang.NullPointerException. 来自:CSDN博客推荐文章   |  时间:2012 ...

  4. 在命令行中运行JUnit测试

    可以在Eclipse之外运行JUnit测试,使用org.junit.runner.JUnitCore类. 这个类提供了runClasses()方法,它允许运行一个或多个测试类.runClasses() ...

  5. ZooKeeper系列之二:Zookeeper常用命令

    https://my.oschina.net/u/347386/blog/313037

  6. java线程安全问题之静态变量、实例变量、局部变量

    java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同<java并发编程实践>中所说: 写道 给线程安全下定义比较困难.存在很多种定义,如 ...

  7. 查看已装TensorFlow的版本和路径

    pyhton Python 2.7.14... >>>import tensorflow as tf >>>tf.__version__ '1.3.0'>&g ...

  8. Mac mysql 解决中文乱码

    Mac mysql 解决中文乱码问题 出现"???"之类的无法识别的乱码 到/etc目录下自己建一个my.cnf文件(需要最高权限,使用sudo su),然后写入内容: [clie ...

  9. 在PC上运行安卓(Android)应用程序的4个方法

    我有一部荣耀3C,一般放在宿舍(我随身携带的是一部诺基亚E63,小巧.稳定.待机时间长),在宿舍我就会用它在微信上看公众号里的文章,最近要考驾照也在上面用驾考宝典.最近想在实验室用这两个软件,但又懒得 ...

  10. tomcat和nginx的使用

    1.下载tomcat,配置conf/server.xml,在Host节点下添加Context节点,指定程序目录: <Context path="/ol" docBase=&q ...