zoukankan      html  css  js  c++  java
  • C# 异步编程 结束异步调用

    在使用 BeginInvoke 和 EndInvoke 进行异步调用时,调用 BeginInvoke 之后,可以执行下列操作来结束异步调用:

    · 进行某些操作,然后调用 EndInvoke 一直阻止到调用完成。

    · 使用 IAsyncResult..::.AsyncWaitHandle 属性获取 WaitHandle,使用它的 WaitOne 方法一直阻止执行直到发出 WaitHandle 信号,然后调用 EndInvoke。

    · 轮询由 BeginInvoke 返回的 IAsyncResult,确定异步调用何时完成,然后调用 EndInvoke。

    · 将用于回调方法的委托传递给 BeginInvoke。异步调用完成后,将在 ThreadPool 线程上执行该方法。该回调方法将调用 EndInvoke。

    异步委托

    下面的代码演示异步调用同一个长时间运行的方法 TestMethod 的各种方式。TestMethod 方法会显示一条控制台消息,说明它已开始处理,休眠了几秒钟,然后结束。TestMethod 有一个 out 参数,该参数用于演示此种参数添加到 BeginInvoke 和 EndInvoke 的签名中的方式。可以按同样的方式处理 ref 参数。

    TestMethod 的定义和名为 AsyncMethodCaller 的、可用来异步调用 TestMethod 的委托。若要编译任何代码示例,必须包括 TestMethod 的定义和 AsyncMethodCaller 委托。

    using System;
    using System.Threading; 
    
    namespace Examples.AdvancedProgramming.AsynchronousOperations
    {
        public class AsyncDemo 
        {
            // The method to be executed asynchronously.
            public string TestMethod(int callDuration, out int threadId) 
            {
                Console.WriteLine("Test method begins.");
                Thread.Sleep(callDuration);
                threadId = Thread.CurrentThread.ManagedThreadId;
                return String.Format("My call time was {0}.", callDuration.ToString());
            }
        }
        // The delegate must have the same signature as the method
        // it will call asynchronously.
        public delegate string AsyncMethodCaller(int callDuration, out int threadId);
    }
    

    使用 EndInvoke 等待异步调用

    异步执行方法最简单的方式是通过调用委托的 BeginInvoke 方法来开始执行方法,在主线程上执行一些工作,然后调用委托的 EndInvoke 方法。EndInvoke 可能会阻止调用线程,因为它直到异步调用完成之后才返回。这种技术非常适合文件或网络操作,但是由于 EndInvoke 会阻止它,所以不要从服务于用户界面的线程中调用它。

    using System;
    using System.Threading;
    
    namespace Examples.AdvancedProgramming.AsynchronousOperations
    {
        public class AsyncMain 
        {
            public static void Main() 
            {
                // The asynchronous method puts the thread id here.
                int threadId;
    
                // Create an instance of the test class.
                AsyncDemo ad = new AsyncDemo();
    
                // Create the delegate.
                AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
    
                // Initiate the asychronous call.
                IAsyncResult result = caller.BeginInvoke(3000, 
                    out threadId, null, null);
    
                Thread.Sleep(0);
                Console.WriteLine("Main thread {0} does some work.",
                    Thread.CurrentThread.ManagedThreadId);
    
                // Call EndInvoke to wait for the asynchronous call to complete,
                // and to retrieve the results.
                string returnValue = caller.EndInvoke(out threadId, result);
    
                Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",
                    threadId, returnValue);
            }
        }
    }
    

    使用 WaitHandle 等待异步调用

    您可以使用 BeginInvoke 返回的 IAsyncResult 的 AsyncWaitHandle 属性来获取 WaitHandle。异步调用完成时会发出 WaitHandle 信号,而您可以通过调用 WaitOne 方法等待它。

    如果您使用 WaitHandle,则在异步调用完成之前或之后,在通过调用 EndInvoke 检索结果之前,还可以执行其他处理。

    using System;
    using System.Threading;
    
    namespace Examples.AdvancedProgramming.AsynchronousOperations
    {
        public class AsyncMain 
        {
            static void Main() 
            {
                // The asynchronous method puts the thread id here.
                int threadId;
    
                // Create an instance of the test class.
                AsyncDemo ad = new AsyncDemo();
    
                // Create the delegate.
                AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
    
                // Initiate the asychronous call.
                IAsyncResult result = caller.BeginInvoke(3000, 
                    out threadId, null, null);
    
                Thread.Sleep(0);
                Console.WriteLine("Main thread {0} does some work.",
                    Thread.CurrentThread.ManagedThreadId);
    
                // Wait for the WaitHandle to become signaled.
                result.AsyncWaitHandle.WaitOne();
    
                // Perform additional processing here.
                // Call EndInvoke to retrieve the results.
                string returnValue = caller.EndInvoke(out threadId, result);
    
                Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",
                    threadId, returnValue);
            }
        }
    }
    
    

    轮询异步调用完成

    您可以使用由 BeginInvoke 返回的 IAsyncResult 的 IsCompleted 属性来发现异步调用何时完成。从用户界面的服务线程中进行异步调用时可以执行此操作。轮询完成允许调用线程在异步调用在 ThreadPool 线程上执行时继续执行。

    using System;
    using System.Threading;
    
    namespace Examples.AdvancedProgramming.AsynchronousOperations
    {
        public class AsyncMain 
        {
            static void Main() {
                // The asynchronous method puts the thread id here.
                int threadId;
    
                // Create an instance of the test class.
                AsyncDemo ad = new AsyncDemo();
    
                // Create the delegate.
                AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
    
                // Initiate the asychronous call.
                IAsyncResult result = caller.BeginInvoke(3000, 
                    out threadId, null, null);
    
                // Poll while simulating work.
                while(result.IsCompleted == false) {
                    Thread.Sleep(10);
                }
    
                // Call EndInvoke to retrieve the results.
                string returnValue = caller.EndInvoke(out threadId, result);
    
                Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",
                    threadId, returnValue);
            }
        }
    

    异步调用完成时执行回调方法

    如果启动异步调用的线程不需要是处理结果的线程,则可以在调用完成时执行回调方法。回调方法在 ThreadPool 线程上执行。

    若要使用回调方法,必须将引用回调方法的 AsyncCallback 委托传递给 BeginInvoke。也可以传递包含回调方法将要使用的信息的对象。例如,可以传递启动调用时曾使用的委托,以便回调方法能够调用 EndInvoke。

    using System;
    using System.Threading;
    
    namespace Examples.AdvancedProgramming.AsynchronousOperations
    {
        public class AsyncMain 
        {
            // Asynchronous method puts the thread id here.
            private static int threadId;
    
            static void Main() {
                // Create an instance of the test class.
                AsyncDemo ad = new AsyncDemo();
    
                // Create the delegate.
                AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
    
                // Initiate the asychronous call.  Include an AsyncCallback
                // delegate representing the callback method, and the data
                // needed to call EndInvoke.
                IAsyncResult result = caller.BeginInvoke(3000,
                    out threadId, 
                    new AsyncCallback(CallbackMethod),
                    caller );
    
                Console.WriteLine("Press Enter to close application.");
                Console.ReadLine();
            }
    
            // Callback method must have the same signature as the
            // AsyncCallback delegate.
            static void CallbackMethod(IAsyncResult ar) 
            {
                // Retrieve the delegate.
                AsyncMethodCaller caller = (AsyncMethodCaller) ar.AsyncState;
    
                // Call EndInvoke to retrieve the results.
                string returnValue = caller.EndInvoke(out threadId, ar);
    
                Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",
                    threadId, returnValue);
            }
        }
    }
    
    
    
  • 相关阅读:
    HDOJ 1846 Brave Game
    并查集模板
    HDU 2102 A计划
    POJ 1426 Find The Multiple
    POJ 3278 Catch That Cow
    POJ 1321 棋盘问题
    CF 999 C.Alphabetic Removals
    CF 999 B. Reversing Encryption
    string的基础用法
    51nod 1267 4个数和为0
  • 原文地址:https://www.cnblogs.com/luoht/p/1839804.html
Copyright © 2011-2022 走看看