旋风

Communication comes from our hears and heads! my msn:youpeizun@hotmail.com


导航

BeginInvoke四种异步调用学习体会

Posted on 2006-03-08 12:43  xuanfeng  阅读(576)  评论(0编辑  收藏  举报

以下内容摘之于MSDN,并结合自己加一些自己的看法:我学得这可以让让想了解用BeginInvoke来进生异步调用的人会有一个全面的了解:

  • 进行某些操作,然后调用 EndInvoke 一直阻塞到调用完成。
  • 使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,使用它的 WaitOne 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用 EndInvoke
  • 轮询由 BeginInvoke 返回的 IAsyncResult,确定异步调用何时完成,然后调用 EndInvoke
  • 将用于回调方法的委托传递给 BeginInvoke。该方法在异步调用完成后在 ThreadPool 线程上执行,它可以调用 EndInvoke
  •     我觉得所为的异步调用是通过1.Thread.Sleep(),来控制主线程与BenginInovke线程的执行先后顺序.
    2.通过EndInvoke来阻塞让线程,让BeginInvoke线程来执行.
    3.回调方法无论如何都是要等等BeginInvoke所代理的方法先执行完,它才会执行.但,它们用的都是BeginInvoke 的线程;
       如果去掉上面的条件,那么就变成同步调用啦.

    以下提代码测试: 

  • using System;
    using System.Threading; 
        //公共测试类
    public class AsyncDemo {
        
    // The method to be executed asynchronously.
        
     public string TestMethod(int callDuration, out int threadId) {
            Console.WriteLine(
    "Test method begins.");
       //使用该线程休眠,让主线程完成EndInvoke这之前的代码.为什么这么说呢,因为EndInove会阻塞主线程直到调//用完毕,并取得返回值:
            Thread.Sleep(callDuration);
            threadId 
    = AppDomain.GetCurrentThreadId();
            
    return "MyCallTime was " + callDuration.ToString();
        }

    }

    //使用 EndInvoke 等待异步调用测试主类
    public class AsyncMain {
        
    static void Main(string[] args) {
            
    // The asynchronous method puts the thread id here.
            int threadId;

            
    // Create an instance of the test class.
            AsyncDemo ad = new AsyncDemo();

            
    // Create the delegate.
            AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
       
            
    // Initiate the asychronous call.
            IAsyncResult ar = dlgt.BeginInvoke(3000
                
    out threadId, nullnull);
    //注意,在此,threadid并没有改变.直到EndInove;在这里这要提到一个得得就是,我们知道,定义Delegate的//时候其形参不能包含有out关关键字的,我也不太明白这里,应该是个特例吧!
            Thread.Sleep(
    0);
            Console.WriteLine(
    "Main thread {0} does some work.",
                AppDomain.GetCurrentThreadId());

            
    // Call EndInvoke to Wait for the asynchronous call to complete,
            
    // and to retrieve the results.
            string ret = dlgt.EndInvoke(out threadId, ar);

            Console.WriteLine(
    "The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
        }

    }


    //使用 WaitHandle 等待异步调用测试主类

    public class AsyncMain {
        
    static void Main(string[] args) {
            
    // The asynchronous method puts the thread id here.
            int threadId;

            
    // Create an instance of the test class.
            AsyncDemo ad = new AsyncDemo();

            
    // Create the delegate.
            AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
       
            
    // Initiate the asychronous call.
            IAsyncResult ar = dlgt.BeginInvoke(3000
                
    out threadId, nullnull);

            Thread.Sleep(
    0);
            Console.WriteLine(
    "Main thread {0} does some work.",
                AppDomain.GetCurrentThreadId());

            
    // Wait for the WaitHandle to become signaled.
            ar.AsyncWaitHandle.WaitOne();
         //上面一句可以让Invoke线程先停止运行,先执行下面语句直到EndInvoke.
                    //可以在这里添加你要运行的代码.
            
    // Perform additional processing here.
            
    // Call EndInvoke to retrieve the results.
            string ret = dlgt.EndInvoke(out threadId, ar);

            Console.WriteLine(
    "The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
        }

    }



    //轮询异步调用完成测试主类

    public class AsyncMain {
        
    static void Main(string[] args) {
            
    // The asynchronous method puts the thread id here.
            int threadId;

            
    // Create an instance of the test class.
            AsyncDemo ad = new AsyncDemo();

            
    // Create the delegate.
            AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
       
            
    // Initiate the asychronous call.
            IAsyncResult ar = dlgt.BeginInvoke(3000
                
    out threadId, nullnull);

            
    // Poll while simulating work.
    //下面语句控主线程让,让Invoke线程运行完毕;
            while(ar.IsCompleted == false{
                Thread.Sleep(
    10);
            }


            
    // Call EndInvoke to retrieve the results.
            string ret = dlgt.EndInvoke(out threadId, ar);

            Console.WriteLine(
    "The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
        }

    }


    //异步调用完成时执行回调方法测试主类
    public class AsyncMain {
        
    // Asynchronous method puts the thread id here.
        private static int threadId;

        
    static void Main(string[] args) {
            
    // Create an instance of the test class.
            AsyncDemo ad = new AsyncDemo();

            
    // Create the delegate.
            AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
       
            
    // Initiate the asychronous call.  Include an AsyncCallback
            
    // delegate representing the callback method, and the data
            
    // needed to call EndInvoke.
            IAsyncResult ar = dlgt.BeginInvoke(3000,
                
    out threadId, 
                
    new AsyncCallback(CallbackMethod),
                dlgt );

            Console.WriteLine(
    "Press Enter to close application.");
            Console.ReadLine();
        }

        
        
    // Callback method must have the same signature as the
        
    // AsyncCallback delegate.
    //下面那个回调方法,只有等到BeginInvoke所调用的代理方法执行完毕才会执行,但它们用的是同一条线程,而不是与主线程相同.
        static void CallbackMethod(IAsyncResult ar) {
            
    // Retrieve the delegate.
            AsyncDelegate dlgt = (AsyncDelegate) ar.AsyncState;

            
    // Call EndInvoke to retrieve the results.
            string ret = dlgt.EndInvoke(out threadId, ar);

            Console.WriteLine(
    "The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
        }

    }