精华内容
下载资源
问答
  • C#异步调用四大方法

    2020-12-22 19:57:14
    C#异步调用四大方法是什么呢?C#异步调用四大方法的使用是如何进行的呢?让我们首先了解下什么时候用到C#异步调用:  .NET Framework 允许您C#异步调用任何方法。定义与您需要调用的方法具有相同签名的委托;公共...
  • C#异步调用

    2011-11-21 12:59:23
    异步 Web 方法的工作原理 何时采用异步 Web 方法 使用异步 Web 方法聚合数据
  • C#异步调用实例小结

    2020-09-03 10:53:55
    主要介绍了C#异步调用的方法,实例分析了C#同步调用及异步调用的常用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
  • C#异步调用示例详解

    2020-08-30 07:54:46
    主要为大家详细介绍了C#异步调用的示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 他们各自的作用是什么呢那么本文就向你介绍C#异步调用四大方法的具体内容 AD C#异步调用四大方法是什么呢C#异步调用四大方法的使用是如何进行的呢让我们首先了解下什么时候用到C#异步调用 .NET Framework 允许您C#...
  • C#异步调用四大方法详解

    千次阅读 2019-08-01 12:03:53
    C#异步调用四大方法是什么呢?C#异步调用四大方法的使用是如何进行的呢?让我们首先了解下什么时候用到C#异步调用: .NET Framework 允许您C#异步调用任何方法。定义与您需要调用的方法具有相同签名的委托;公共...

    C#异步调用四大方法是什么呢?C#异步调用四大方法的使用是如何进行的呢?让我们首先了解下什么时候用到C#异步调用:

    .NET Framework 允许您C#异步调用任何方法。定义与您需要调用的方法具有相同签名的委托;公共语言运行库将自动为该委托定义具有适当签名的 BeginInvoke 和 EndInvoke 方法。

    BeginInvoke 方法用于启动C#异步调用。它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数(将在稍后描述)。BeginInvoke 立即返回,不等待C#异步调用完成。BeginInvoke 返回 IasyncResult,可用于监视调用进度。

    EndInvoke 方法用于检索C#异步调用结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;如果C#异步调用未完成,EndInvoke 将一直阻塞到C#异步调用完成。EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数(在 Visual Basic 中为 ByRef 和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。

    注意   Visual Studio .NET 中的智能感知功能会显示 BeginInvoke 和 EndInvoke 的参数。如果您没有使用 Visual Studio 或类似的工具,或者您使用的是 C# 和 Visual Studio .NET,请参见异步方法签名获取有关运行库为这些方法定义的参数的描述。

    本主题中的代码演示了四种使用 BeginInvoke 和 EndInvoke 进行C#异步调用的常用方法。调用了 BeginInvoke 后,可以:

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

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

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

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

    警告:始终在C#异步调用完成后调用 EndInvoke。

    测试方法和异步委托

    四个示例全部使用同一个长期运行的测试方法 TestMethod。该方法显示一个表明它已开始处理的控制台信息,休眠几秒钟,然后结束。TestMethod 有一个 out 参数(在 Visual Basic 中为 ByRef),它演示了如何将这些参数添加到 BeginInvoke 和 EndInvoke 的签名中。您可以用类似的方式处理 ref 参数(在 Visual Basic 中为 ByRef)。

    下面的代码示例显示 TestMethod 以及代表 TestMethod 的委托;若要使用任一示例,请将示例代码追加到这段代码中。

    注意   为了简化这些示例,TestMethod 在独立于 Main() 的类中声明。或者,TestMethod 可以是包含 Main() 的同一类中的 static 方法(在 Visual Basic 中为 Shared)。

    1. using System;  
    2. using System.Threading;   
    3.  
    4. public class AsyncDemo {  
    5. // The method to be executed asynchronously.  
    6. //  
    7. public string TestMethod(  
    8. int callDuration, out int threadId) {  
    9. Console.WriteLine("Test method begins.");  
    10. Thread.Sleep(callDuration);  
    11. threadId = AppDomain.GetCurrentThreadId();  
    12. return "MyCallTime was " + callDuration.ToString();  
    13. }  
    14. }  
    15.  
    16. // The delegate must have the same signature as the method  
    17. // you want to call asynchronously.  
    18. public delegate string AsyncDelegate(  
    19. int callDuration, out int threadId);  
    20.    
    21.  
    22. using System;  
    23. using System.Threading;   
    24.  
    25. public class AsyncDemo {  
    26. // The method to be executed asynchronously.  
    27. //  
    28. public string TestMethod(  
    29. int callDuration, out int threadId) {  
    30. Console.WriteLine("Test method begins.");  
    31. Thread.Sleep(callDuration);  
    32. threadId = AppDomain.GetCurrentThreadId();  
    33. return "MyCallTime was " + callDuration.ToString();  
    34. }  
    35. }  
    36.  
    37. // The delegate must have the same signature as the method  
    38. // you want to call asynchronously.  
    39. public delegate string AsyncDelegate(  
    40. int callDuration, out int threadId); 

    C#异步调用四大方法之使用 EndInvoke 等待异步调用

    异步执行方法的最简单方式是以 BeginInvoke 开始,对主线程执行一些操作,然后调用 EndInvoke。EndInvoke 直到C#异步调用完成后才返回。这种技术非常适合文件或网络操作,但是由于它阻塞 EndInvoke,所以不要从用户界面的服务线程中使用它。

    1. public class AsyncMain {  
    2. static void Main(string[] args) {  
    3. // The asynchronous method puts the thread id here.  
    4. int threadId;  
    5.  
    6. // Create an instance of the test class.  
    7. AsyncDemo ad = new AsyncDemo();  
    8.  
    9. // Create the delegate.  
    10. AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);  
    11.      
    12. // Initiate the asychronous call.  
    13. IAsyncResult ar = dlgt.BeginInvoke(3000,   
    14. out threadId, nullnull);  
    15.  
    16. Thread.Sleep(0);  
    17. Console.WriteLine("Main thread {0} does some work.",  
    18. AppDomain.GetCurrentThreadId());  
    19.  
    20. // Call EndInvoke to Wait for   
    21. //the asynchronous call to complete,  
    22. // and to retrieve the results.  
    23. string ret = dlgt.EndInvoke(out threadId, ar);  
    24.  
    25. Console.WriteLine("The call executed on thread {0},   
    26. with return value \"{1}\".", threadId, ret);  
    27. }  

    C#异步调用四大方法之使用 WaitHandle 等待异步调用

    等待 WaitHandle 是一项常用的线程同步技术。您可以使用由 BeginInvoke 返回的 IAsyncResult 的 AsyncWaitHandle 属性来获取 WaitHandle。C#异步调用完成时会发出 WaitHandle 信号,而您可以通过调用它的 WaitOne 等待它。

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

    1. public class AsyncMain {  
    2. static void Main(string[] args) {  
    3. // The asynchronous method puts the thread id here.  
    4. int threadId;  
    5.  
    6. // Create an instance of the test class.  
    7. AsyncDemo ad = new AsyncDemo();  
    8.  
    9. // Create the delegate.  
    10. AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);  
    11.      
    12. // Initiate the asychronous call.  
    13. IAsyncResult ar = dlgt.BeginInvoke(3000,   
    14. out threadId, nullnull);  
    15.  
    16. Thread.Sleep(0);  
    17. Console.WriteLine("Main thread {0} does some work.",  
    18. AppDomain.GetCurrentThreadId());  
    19.  
    20. // Wait for the WaitHandle to become signaled.  
    21. ar.AsyncWaitHandle.WaitOne();  
    22.  
    23. // Perform additional processing here.  
    24. // Call EndInvoke to retrieve the results.  
    25. string ret = dlgt.EndInvoke(out threadId, ar);  
    26.  
    27. Console.WriteLine("The call executed on thread {0},   
    28. with return value \"{1}\".", threadId, ret);  
    29. }  

    C#异步调用四大方法之轮询异步调用完成

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

    1. public class AsyncMain {  
    2. static void Main(string[] args) {  
    3. // The asynchronous method puts the thread id here.  
    4. int threadId;  
    5.  
    6. // Create an instance of the test class.  
    7. AsyncDemo ad = new AsyncDemo();  
    8.  
    9. // Create the delegate.  
    10. AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);  
    11.      
    12. // Initiate the asychronous call.  
    13. IAsyncResult ar = dlgt.BeginInvoke(3000,   
    14. out threadId, nullnull);  
    15.  
    16. // Poll while simulating work.  
    17. while(ar.IsCompleted == false) {  
    18. Thread.Sleep(10);  
    19. }  
    20.  
    21. // Call EndInvoke to retrieve the results.  
    22. string ret = dlgt.EndInvoke(out threadId, ar);  
    23.  
    24. Console.WriteLine("The call executed on thread {0},  
    25.  with return value \"{1}\".", threadId, ret);  
    26. }  

    C#异步调用四大方法之异步调用完成时执行回调方法

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

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

    1. public class AsyncMain {  
    2. // Asynchronous method puts the thread id here.  
    3. private static int threadId;  
    4.  
    5. static void Main(string[] args) {  
    6. // Create an instance of the test class.  
    7. AsyncDemo ad = new AsyncDemo();  
    8.  
    9. // Create the delegate.  
    10. AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);  
    11.      
    12. // Initiate the asychronous call.  Include an AsyncCallback  
    13. // delegate representing the callback method, and the data  
    14. // needed to call EndInvoke.  
    15. IAsyncResult ar = dlgt.BeginInvoke(3000,  
    16. out threadId,   
    17. new AsyncCallback(CallbackMethod),  
    18. dlgt );  
    19.  
    20. Console.WriteLine("Press Enter to close application.");  
    21. Console.ReadLine();  
    22. }  
    23.  
    24. // Callback method must have the same signature as the  
    25. // AsyncCallback delegate.  
    26. static void CallbackMethod(IAsyncResult ar) {  
    27. // Retrieve the delegate.  
    28. AsyncDelegate dlgt = (AsyncDelegate) ar.AsyncState;  
    29.  
    30. // Call EndInvoke to retrieve the results.  
    31. string ret = dlgt.EndInvoke(out threadId, ar);  
    32.  
    33. Console.WriteLine("The call executed on thread {0},  
    34.  with return value \"{1}\".", threadId, ret);  
    35. }  
    36. }  

    C#异步调用四大方法的基本内容就向你介绍到这里,希望对你了解和学习C#异步调用有所帮助。

    转载于:https://www.cnblogs.com/Renxf/p/3435241.html

    展开全文
  • C# 异步调用

    千次阅读 2007-12-28 14:49:00
    异步操作通常用于执行完成时间可能较长的任务,如打开大文件、连接远程计算机...进行异步调用时,需要定义与异步调用的方法具有相同签名的委托。公共语言运行时会自动使用适当的签名为该委托定义BeginInvoke和EndInvok

    异步操作通常用于执行完成时间可能较长的任务,如打开大文件、连接远程计算机或查询数据库。异步操作在主应用程序线程以外的线程中执行。应用程序调用方法异步执行某个操作时,应用程序可在异步方法执行其任务时继续执行。

    .NET框架能够对任何方法进行异步调用。进行异步调用时,需要定义与异步调用的方法具有相同签名的委托。公共语言运行时会自动使用适当的签名为该委托定义BeginInvoke和EndInvoke方法。

    BeginInvoke方法用于启动异步调用。它与需要异步执行的方法具有相同的参数。此外,它还有两个可选参数。第一个参数是一个AsyncCallback委托,该委托引用在异步调用完成时要调用的方法。第二个参数是一个用户定义的对象,该对象可向回调方法传递数据。BeginInvoke立即返回,不会等待异步调用完成,被调用的方法将在线程池线程中执行。因此,提交请求的原始线程与执行异步方法的线程池线程是并行执行的。BeginInvoke会返回一个IAsyncResult对象,可以使用该对象来监视异步调用进度,也可将该对象传递给EndInvoke方法,以获取异步执行的方法的返回值。

    EndInvoke方法用于检索异步调用的结果。调用BeginInvoke方法后可随时调用EndInvoke方法;如果异步调用尚未完成,EndInvoke方法将一直阻塞调用线程,直到异步调用完成后才允许调用线程执行。EndInvoke方法的参数包括需要异步执行的方法的out和ref参数,以及由BeginInvoke返回的IAsyncResult对象。因此,通过EndInvoke方法可以获得异步调用的方法的所有输出数据,包括返回值、out和ref参数。

    AsyncCallback委托表示在异步操作完成时调用的回调方法,其定义如下:

    public delegate void AsyncCallback(IAsyncResult ar);

    System.IAsyncResult接口表示异步操作的状态。IAsyncResult接口由包含可异步操作的方法的类实现。它是启动异步操作的方法的返回类型,也是结束异步操作的方法的第三个参数的类型。当异步操作完成时,IAsyncResult对象也将传递给由AsyncCallback委托调用的方法。支持IAsyncResult接口的对象存储异步操作的状态信息,并提供同步对象以允许线程在操作完成时终止。IAsyncResult接口定义了四个公开属性,通过它们可以获取异步调用的状态。

    —  AsyncState:获取用户定义的对象,它限定或包含关于异步操作的信息。

    —  AsyncWaitHandle:获取用于等待异步操作完成的 WaitHandle。

    —  CompletedSynchronously:获取异步操作是否同步完成的指示。

    —  IsCompleted:获取异步操作是否已完成的指示。

    使用BeginInvoke和EndInvoke进行异步调用的常用方法主要有四种:

    — 调用BeginInvoke方法启动异步方法,进行某些操作,然后调用EndInvoke方法来一直阻止请求线程到调用完成。

    — 调用BeginInvoke方法启动异步方法,使用System.IAsyncResult.AsyncWaitHandle属性获取WaitHandle,使用它的WaitOne方法一直阻止执行直到发出WaitHandle信号,然后调用EndInvoke方法。

    — 调用BeginInvoke方法启动异步方法,轮询由BeginInvoke返回的IAsyncResult,确定异步调用何时完成,然后调用EndInvoke。

    — 调用BeginInvoke方法启动异步方法时,将代表异步方法完成时需要回调的方法的委托传递给BeginInvoke。异步调用完成后,将在ThreadPool线程上执行该回调方法。在该回调方法中调用EndInvoke。

    每种方法都是通过BeginInvoke方法来启动异步方法,调用EndInvoke方法来完成异步调用。

    1.直接调用EndInvoke 方法等待异步调用结束

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

    下面的代码说明了如何使用这种方法来进行异步调用,并获得异步方法的结果:

    // AsynCall1.cs

    // 异步调用示例: 直接调用EndInvoke 方法等待异步调用结束

    using System;

    using System.Threading;

    // 定义异步调用方法的委托

    // 它的签名必须与要异步调用的方法一致

    public delegate int AsynComputeCaller(ulong l, out ulong factorial);

    public class Factorial

    {

        // 计算阶乘

        public ulong Compute(ulong l)

        {

            // 不要太快 :-)

            Thread.Sleep(50);

            if (l == 1)

            {

                return 1;

            }

            else

            {

                return l * Compute(l - 1);

            }

        }

        // 要异步调用的方法

        // 1. 调用Factorial方法来计算阶乘,并用out参数返回

        // 2. 统计计算阶乘所用的时间,并返回该值

        public int AsynCompute(ulong l, out ulong factorial)

        {

            Console.WriteLine("开始异步方法");

           

            DateTime startTime = DateTime.Now;

            factorial = Compute(l);

            TimeSpan usedTime =

                          new TimeSpan(DateTime.Now.Ticks - startTime.Ticks);

           

            Console.WriteLine("结束异步方法");

            return usedTime.Milliseconds;

        }

    }

    public class Test

    {

        public static void Main()

        {

            // 创建包含异步方法的类的实例

            Factorial fact = new Factorial();

            // 创建异步委托

            AsynComputeCaller caller = new AsynComputeCaller(fact.AsynCompute);

            Console.WriteLine("启动异步调用");

            ulong l = 30;

            ulong lf;

            // 启动异步调用

            IAsyncResult result = caller.BeginInvoke(l, out lf, null, null);

            // 主线程进行一些操作

            Thread.Sleep(0);

            Console.WriteLine("主线程进行一些操作");

            // 调用EndInvoke来等待异步调用结束,并获得结果

            int returnValue = caller.EndInvoke(out lf, result);

            // 异步调用的方法已经结束,显示结果

            Console.WriteLine("已经得到结果:{0}的阶乘为{1},计算时间为{2}毫秒",

                                   l, lf, returnValue);

        }

    }

     

    2.使用 WaitHandle 等待异步调用结束

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

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

    下面的代码说明了如何使用这种方法来进行异步调用,并获得异步方法的结果:

    // AsynCall2.cs

    // 异步调用示例:使用 WaitHandle 等待异步调用结束

    using System;

    using System.Threading;

    // 定义异步调用方法的委托

    // 它的签名必须与要异步调用的方法一致

    public delegate int AsynComputeCaller(ulong l, out ulong factorial);

    public class Factorial

    {

        // 计算阶乘

        public ulong Compute(ulong l)

        {

            // 不要太快 :-)

            Thread.Sleep(50);

            if (l == 1)

            {

                return 1;

            }

            else

            {

                return l * Compute(l - 1);

            }

        }

        // 要异步调用的方法

        // 1. 调用Factorial方法来计算阶乘,并用out参数返回

        // 2. 统计计算阶乘所用的时间,并返回该值

        public int AsynCompute(ulong l, out ulong factorial)

        {

            Console.WriteLine("开始异步方法");

           

            DateTime startTime = DateTime.Now;

            factorial = Compute(l);

            TimeSpan usedTime =

                            new TimeSpan(DateTime.Now.Ticks - startTime.Ticks);

           

            Console.WriteLine("结束异步方法");

            return usedTime.Milliseconds;

        }

    }

    public class Test

    {

        public static void Main()

        {

            // 创建包含异步方法的类的实例

            Factorial fact = new Factorial();

            // 创建异步委托

            AsynComputeCaller caller = new AsynComputeCaller(fact.AsynCompute);

            Console.WriteLine("启动异步调用");

            ulong l = 30;

            ulong lf;

            // 启动异步调用

            IAsyncResult result = caller.BeginInvoke(l, out lf, null, null);

            // 主线程进行一些操作

            Thread.Sleep(0);

            Console.WriteLine("主线程进行一些操作");

            // 等待WaitHandle接收到信号

            Console.WriteLine("等待WaitHandle接收到信号");

            result.AsyncWaitHandle.WaitOne();

            // 主线程进行一些操作

            Thread.Sleep(0);

            Console.WriteLine("异步方法已经结束,主线程进行另外一些操作");

            // 调用EndInvoke来获得结果

            int returnValue = caller.EndInvoke(out lf, result);

            // 异步调用的方法已经结束,显示结果

            Console.WriteLine("{0}的阶乘为{1},计算时间为{2}毫秒",

                                  l, lf, returnValue);

        }

    }

    3.轮询异步调用是否完成

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

    下面的代码说明了如何使用这种方法来进行异步调用,并获得异步方法的结果:

    // AsynCall3.cs

    // 异步调用示例: 轮询异步调用是否完成

    using System;

    using System.Threading;

    // 定义异步调用方法的委托

    // 它的签名必须与要异步调用的方法一致

    public delegate int AsynComputeCaller(ulong l, out ulong factorial);

    public class Factorial

    {

        // 计算阶乘

        public ulong Compute(ulong l)

        {

            // 不要太快 :-)

            Thread.Sleep(50);

            if (l == 1)

            {

                return 1;

            }

            else

            {

                return l * Compute(l - 1);

            }

        }

        // 要异步调用的方法

        // 1. 调用Factorial方法来计算阶乘,并用out参数返回

        // 2. 统计计算阶乘所用的时间,并返回该值

        public int AsynCompute(ulong l, out ulong factorial)

        {

            Console.WriteLine("开始异步方法");

           

            DateTime startTime = DateTime.Now;

            factorial = Compute(l);

            TimeSpan usedTime =

                                   new TimeSpan(DateTime.Now.Ticks - startTime.Ticks);

           

            Console.WriteLine("/n结束异步方法");

            return usedTime.Milliseconds;

        }

    }

    public class Test

    {

        public static void Main()

        {

            // 创建包含异步方法的类的实例

            Factorial fact = new Factorial();

            // 创建异步委托

            AsynComputeCaller caller = new AsynComputeCaller(fact.AsynCompute);

            Console.WriteLine("启动异步调用");

            ulong l = 30;

            ulong lf;

            // 启动异步调用

            IAsyncResult result = caller.BeginInvoke(l, out lf, null, null);

            // 轮询异步方法是否结束

            Console.WriteLine("主线程进行一些操作");

            while (result.IsCompleted == false)

            {

                // 主线程进行一些操作

                Thread.Sleep(10);

                Console.Write(".");

            }

            // 主线程进行一些操作

            Thread.Sleep(0);

            Console.WriteLine("异步方法已经结束,主线程进行另外一些操作");

            // 调用EndInvoke来获得结果

            int returnValue = caller.EndInvoke(out lf, result);

            // 异步调用的方法已经结束,显示结果

            Console.WriteLine("已经得到结果:{0}的阶乘为{1},计算时间为{2}毫秒",

                                   l, lf, returnValue);

        }

    }

     

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

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

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

    下面的代码说明了如何使用这种方法来进行异步调用,并获得异步方法的结果:

    // AsynCall4.cs

    // 异步调用示例: 在异步调用完成时执行回调方法

    using System;

    using System.Threading;

    // 定义异步调用方法的委托

    // 它的签名必须与要异步调用的方法一致

    public delegate int AsynComputeCaller(ulong l, out ulong factorial);

    public class Factorial

    {

        // 计算阶乘

        public ulong Compute(ulong l)

        {

            // 不要太快 :-)

            Thread.Sleep(50);

            if (l == 1)

            {

                return 1;

            }

            else

            {

                return l * Compute(l - 1);

            }

        }

        // 要异步调用的方法

        // 1. 调用Factorial方法来计算阶乘,并用out参数返回

        // 2. 统计计算阶乘所用的时间,并返回该值

        public int AsynCompute(ulong l, out ulong factorial)

        {

            Console.WriteLine("开始异步方法");

           

            DateTime startTime = DateTime.Now;

            factorial = Compute(l);

            TimeSpan usedTime =

                                   new TimeSpan(DateTime.Now.Ticks - startTime.Ticks);

           

            Console.WriteLine("结束异步方法");

            return usedTime.Milliseconds;

        }

    }

    public class Test

    {

        static ulong l = 30;

        static ulong lf;

        public static void Main()

        {

            // 创建包含异步方法的类的实例

            Factorial fact = new Factorial();

            // 创建异步委托

            AsynComputeCaller caller = new AsynComputeCaller(fact.AsynCompute);

            // 启动异步调用

            Console.WriteLine("启动异步调用");

            IAsyncResult result = caller.BeginInvoke(l, out lf,

                                    new AsyncCallback(CallbackMethod), caller);

            // 主线程进行一些操作

            Thread.Sleep(0);

            Console.WriteLine("主线程进行一些操作");

            Console.WriteLine("按Enter键结束程序...");

            Console.ReadLine();

        }

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

        // 该回调方法的签名必须与AsyncCallback委托一致

        static void CallbackMethod(IAsyncResult ar)

        {

            // 获取委托

            AsynComputeCaller caller = (AsynComputeCaller)ar.AsyncState;

            // 调用EndInvoke来获得结果

            int returnValue = caller.EndInvoke(out lf, ar);

            // 异步调用的方法已经结束,显示结果

            Console.WriteLine("已经得到结果:{0}的阶乘为{1},计算时间为{2}毫秒",

                                   l, lf, returnValue);

        }

    }

    展开全文
  • C#异步调用的好处和方法,罗列了c#异步调用的各种方式.简明易懂
  • C#异步调用资料整理

    2008-06-20 16:12:43
    C#异步调用资料整理
  • C#异步调用的应用实践最经公司工作需要调用一个外部的webservice,同时要将传出的数据进行保存,以自己以前的习惯,就打算逐步操作,失败啊,完全没考虑过用户体验效果,在同事指点下,意识到使用C#异步调用的好处,...

    C#异步调用的应用实践最经公司工作需要调用一个外部的webservice,同时要将传出的数据进行保存,以自己以前的习惯,就打算逐步操作,失败啊,完全没考虑过用户体验效果,在同事指点下,意识到使用C#异步调用的好处,随便将自己找的一些资料留以保存,以戒后误!

    我们要明确,为什么要进行C#异步调用回调?众所周知,普通方法运行,是单线程的,如果中途有大型操作(如:读取大文件,大批量操作数据库,网络传输等),都会导致方法阻塞,表现在界面上就是,程序卡或者死掉,界面元素不动了,不响应了。C#异步调用方法很好的解决了这些问题,C#异步调用执行某个方法,程序立即开辟一个新线程去运行你的方法,主线程包括界面就不会死掉了。C#异步调用如何开始,好理解,现在我们讨论的是如何结束这个C#异步调用出来的新线程。

    首先,C#异步调用出来的新线程,必须回收,不回收是浪费资源的可耻行为,.NET也是不允许的,所以你别想钻空子,俗话说,请神容易送神难,就是这个道理。下面你可以很容易想到,回收分为2种情况:主动回收和被动回收(当然,这是我自己的理解,微软可不是这么说的),主动回收就是,你去监视那个线程,并且等待,当C#异步调用方法完成了,就把C#异步调用线程回收,焦点回归主线程,实际上就是上篇文章《C#C#异步调用初步》的那种情况,BeginInvoke之后又EndInvoke,如果在EndInvoke的时候,该C#异步调用线程没有完成操作,那么整个程序,包括主线程,又在阻塞了,又会出现界面“死”的情况。要想解决这个问题,就使用“被动回收”方式,其中一个重要的办法就是“C#异步调用回调”。

    C#异步调用核心有二:

    A、 用回调函数(本例中为CallBackMethod),C#异步调用结束后,自动调用此回调函数。

    B、 而不在主线程中手工等待C#异步调用结束,如上两例中在主线程中调用EndInvoke。此种方法,是在回调函数中调用EndInvoke的。

    C#异步调用回调的大概流程是这样的:首先启动C#异步调用,启动参数加上C#异步调用结束时执行的方法,然后这个C#异步调用线程就不用管了,最后当这个C#异步调用线程自己完成工作了,就自动执行启动参数里的那个方法,这样确实很省心,可是代码写起来,就很复杂了。

    下面是搜藏的代码:

    
     
    1. //首先准备好,要进行C#异步调用的方法(能C#异步调用的,最好不多线程)  
    2. private string MethodName(int Num, out int Num2)  
    3. {  
    4.  Num2 = Num;  
    5.  return "HelloWorld";  
    6. }   
    7.  
    8. //程序终点  
    9. //C#异步调用完成时,执行的方法(回调方法),  
    10. //此方法只能有IAsyncResult一个参数,但是该参数几乎万能,可以传递object  
    11. private void CallBackMethod(IAsyncResult ar)  
    12. {  
    13.  //从C#异步调用状态ar.AsyncState中,获取委托对象  
    14.  DelegateName dn = (DelegateName)ar.AsyncState;  
    15.  //输出参数  
    16.  int i;   
    17.  
    18.  //一定要EndInvoke,否则你的下场很惨  
    19.  string r = dn.EndInvoke(out i, ar);  
    20.  MessageBox.Show("C#异步调用完成喽!i的值是" i.ToString() ",r的值是" r);  
    21. }   
    22.  
    23. //定义与方法同签名的委托  
    24. private delegate string DelegateName(int Num, out int Num2);   
    25.  
    26. //程序入口  
    27. private void Run()  
    28. {  
    29.  //实例化委托并初赋值  
    30.  DelegateName dn = new DelegateName(MethodName);  
    31.  //输出参数  
    32.  int i;  
    33.  //实例化回调方法  
    34.  //把AsyncCallback看成Delegate你就懂了,  
    35. //实际上AsyncCallback是一种特殊的Delegate,就像Event似的  
    36.  AsyncCallback acb = new AsyncCallback(CallBackMethod);  
    37.  //C#异步调用开始  
    38.  //如果参数acb换成null则表示没有回调方法  
    39.  //最后一个参数dn的地方,可以换成任意对象,  
    40. //该对象可以被回调方法从参数中获取出来,写成null也可以。  
    41. //参数dn相当于该线程的ID,如果有多个C#异步调用线程,  
    42. //可以都是null,但是绝对不能一样,不能是同一个object,否则异常  
    43.  IAsyncResult iar = dn.BeginInvoke(1, out i, acb, dn);  
    44.  //去做别的事  
    45.  //…………  
    46. }   
    47.  
    48. //最后的结果应该是:i=1,r="HelloWorld"  

    另外,如果可以,定义委托的时候可以选择不用过多的修饰:

    
     
    1. /// ﹤summary﹥  
    2. /// 定义委托  
    3. /// ﹤/summary﹥  
    4. /// ﹤returns﹥﹤/returns﹥  
    5. public delegate bool Asyncdelegate();   
    6.  
    7. /// ﹤summary﹥  
    8. /// Callback method must have the same signature as the  
    9. /// AsyncCallback delegate  
    10. /// ﹤/summary﹥  
    11. /// ﹤param name="ar"﹥﹤/param﹥  
    12. private void CallbackMethod(IAsyncResult ar)  
    13. {  
    14. // Retrieve the delegate.  
    15. Asyncdelegate dlgt = (Asyncdelegate)ar.AsyncState;   
    16.  
    17. // Call EndInvoke to retrieve the results.  
    18. dlgt.EndInvoke(ar);  
    19. }  

    其他方法中调用:

    
     
    1. //C#异步调用执行  
    2. //指定委托方法  
    3. Asyncdelegate isgt = new Asyncdelegate(icpInfo.Insert);  
    4. IAsyncResult ar = isgt.BeginInvoke(  
    5. new AsyncCallback(CallbackMethod), isgt); 

    C#异步调用的基本内容就向你介绍到这里,希望对你了解和学习C#异步调用有所帮助。

    转载于:https://www.cnblogs.com/nafio/p/9137557.html

    展开全文
  • C#异步调用四大方法是什么呢?C#异步调用四大方法的使用是如何进行的呢?让我们首先了解下什么时候用到C#异步调用: .NET Framework 允许您C#异步调用任何方法。定义与您需要调用的方法具有相同签名的委托;公共...

    C#异步调用四大方法是什么呢?C#异步调用四大方法的使用是如何进行的呢?让我们首先了解下什么时候用到C#异步调用:

    .NET Framework 允许您C#异步调用任何方法。定义与您需要调用的方法具有相同签名的委托;公共语言运行库将自动为该委托定义具有适当签名的 BeginInvoke 和 EndInvoke 方法。

    BeginInvoke 方法用于启动C#异步调用。它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数(将在稍后描述)。BeginInvoke 立即返回,不等待C#异步调用完成。BeginInvoke 返回 IasyncResult,可用于监视调用进度。

    EndInvoke 方法用于检索C#异步调用结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;如果C#异步调用未完成,EndInvoke 将一直阻塞到C#异步调用完成。EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数(在 Visual Basic 中为 ByRef 和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。

    注意   Visual Studio .NET 中的智能感知功能会显示 BeginInvoke 和 EndInvoke 的参数。如果您没有使用 Visual Studio 或类似的工具,或者您使用的是 C# 和 Visual Studio .NET,请参见异步方法签名获取有关运行库为这些方法定义的参数的描述。

    本主题中的代码演示了四种使用 BeginInvoke 和 EndInvoke 进行C#异步调用的常用方法。调用了 BeginInvoke 后,可以:

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

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

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

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

    警告:始终在C#异步调用完成后调用 EndInvoke。

    测试方法和异步委托

    四个示例全部使用同一个长期运行的测试方法 TestMethod。该方法显示一个表明它已开始处理的控制台信息,休眠几秒钟,然后结束。TestMethod 有一个 out 参数(在 Visual Basic 中为 ByRef),它演示了如何将这些参数添加到 BeginInvoke 和 EndInvoke 的签名中。您可以用类似的方式处理 ref 参数(在 Visual Basic 中为 ByRef)。

    下面的代码示例显示 TestMethod 以及代表 TestMethod 的委托;若要使用任一示例,请将示例代码追加到这段代码中。

    注意   为了简化这些示例,TestMethod 在独立于 Main() 的类中声明。或者,TestMethod 可以是包含 Main() 的同一类中的 static 方法(在 Visual Basic 中为 Shared)。

    1. 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.");  
      Thread.Sleep(callDuration);  
      threadId = AppDomain.GetCurrentThreadId();  
      return "MyCallTime was " + callDuration.ToString();  
      }  
      }  
       
      // The delegate must have the same signature as the method  
      // you want to call asynchronously.  
      public delegate string AsyncDelegate(  
      int callDuration, out int threadId);  
         
       
      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.");  
      Thread.Sleep(callDuration);  
      threadId = AppDomain.GetCurrentThreadId();  
      return "MyCallTime was " + callDuration.ToString();  
      }  
      }  
       
      // The delegate must have the same signature as the method  
      // you want to call asynchronously.  
      public delegate string AsyncDelegate(  
      int callDuration, out int threadId); 

       

    C#异步调用四大方法之使用 EndInvoke 等待异步调用

    异步执行方法的最简单方式是以 BeginInvoke 开始,对主线程执行一些操作,然后调用 EndInvoke。EndInvoke 直到C#异步调用完成后才返回。这种技术非常适合文件或网络操作,但是由于它阻塞 EndInvoke,所以不要从用户界面的服务线程中使用它。

    1. 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, null, null);  
       
      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);  
      }  
      } 

       

    C#异步调用四大方法之使用 WaitHandle 等待异步调用

    等待 WaitHandle 是一项常用的线程同步技术。您可以使用由 BeginInvoke 返回的 IAsyncResult 的 AsyncWaitHandle 属性来获取 WaitHandle。C#异步调用完成时会发出 WaitHandle 信号,而您可以通过调用它的 WaitOne 等待它。

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

    1. 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, null, null);  
       
      Thread.Sleep(0);  
      Console.WriteLine("Main thread {0} does some work.",  
      AppDomain.GetCurrentThreadId());  
       
      // Wait for the WaitHandle to become signaled.  
      ar.AsyncWaitHandle.WaitOne();  
       
      // 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);  
      }  
      } 

       

    C#异步调用四大方法之轮询异步调用完成

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

    1. 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, null, null);  
       
      // Poll while simulating work.  
      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);  
      }  
      } 

       

    C#异步调用四大方法之异步调用完成时执行回调方法

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

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

    1. 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.  
      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);  
      }  
      }  

       

    C#异步调用四大方法的基本内容就向你介绍到这里,希望对你了解和学习C#异步调用有所帮助。

    转载于:https://www.cnblogs.com/AaronBear/p/5944417.html

    展开全文
  • c# 异步调用之异步模式Func<string, IImageRequest, string> downloadString = (address, req) => { var client = new WebClient(); foreach (var header in...
  • C# 异步调用4个方法

    2010-08-31 17:37:00
    让我们首先了解下什么时候用到C#异步调用: .NET Framework 允许您C#异步调用任何方法。定义与您需要调用的方法具有相同签名的委托;公共语言运行库将自动为该委托定义具有适当签名的 BeginInvoke 和 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 48,275
精华内容 19,310
关键字:

c#异步调用

c# 订阅