使用异步方式调用同步方法
2011-03-03 11:49
686 查看
(查询BeginInvoke 2005MSDN 里相关资料,我复制在这里)
.NET Framework 允许您异步调用任何方法。为此,应定义与您要调用的方法具有相同签名的委托;公共语言运行库会自动使用适当的签名为该委托定义
BeginInvoke 和 EndInvoke 方法。
BeginInvoke 方法可启动异步调用。它与您需要异步执行的方法具有相同的参数,另外它还有两个可选参数。第一个参数是一个 AsyncCallback
委托,该委托引用在异步调用完成时要调用的方法。第二个参数是一个用户定义的对象,该对象可向回调方法传递信息。BeginInvoke
立即返回,不等待异步调用完成。BeginInvoke 会返回 IAsyncResult,这个结果可用于监视异步调用进度。
EndInvoke 方法检索异步调用的结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;如果异步调用尚未完成,EndInvoke
将一直阻止调用线程,直到异步调用完成后才允许调用线程执行。EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数(在 Visual
Basic 中为 <Out> ByRef
和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。
本主题中的代码示例演示了四种使用 BeginInvoke 和 EndInvoke 进行异步调用的常用方法。调用 BeginInvoke
之后,您可以执行下列操作:
进行某些操作,然后调用 EndInvoke 一直阻止到调用完成。
使用 System.IAsyncResult.AsyncWaitHandle
属性获取 WaitHandle,使用它的
WaitOne
方法一直阻止执行直到发出 WaitHandle 信号,然后调用 EndInvoke。
轮询由 BeginInvoke 返回的 IAsyncResult,确定异步调用何时完成,然后调用 EndInvoke。
将用于回调方法的委托传递给 BeginInvoke。异步调用完成后,将在 ThreadPool
线程上执行该方法。该回调方法将调用 EndInvoke。
的各种方式。
方法会显示一条控制台消息,说明它已开始处理,休眠了几秒钟,然后结束。
参数,该参数用于演示此种参数添加到 BeginInvoke 和 EndInvoke 的签名中的方式。您可以按同样的方式处理 ref 参数。
下面的代码示例演示
的、可用来异步调用
的定义和
方法。EndInvoke 可能会阻止调用线程,因为它直到异步调用完成之后才返回。这种技术非常适合文件或网络操作,但是由于 EndInvoke
会阻止它,所以不要从服务于用户界面的线程中调用它。
WaitHandle。异步调用完成时会发出 WaitHandle 信号,而您可以通过调用 WaitOne 方法等待它。
如果您使用 WaitHandle,则在异步调用完成之前或之后,在通过调用 EndInvoke 检索结果之前,还可以执行其他处理。
属性来发现异步调用何时完成。从用户界面的服务线程中进行异步调用时可以执行此操作。轮询完成允许调用线程在异步调用在 ThreadPool
线程上执行时继续执行。
若要使用回调方法,必须将引用回调方法的 AsyncCallback 委托传递给
BeginInvoke。也可以传递包含回调方法将要使用的信息的对象。例如,可以传递启动调用时曾使用的委托,以便回调方法能够调用 EndInvoke。
.NET Framework 允许您异步调用任何方法。为此,应定义与您要调用的方法具有相同签名的委托;公共语言运行库会自动使用适当的签名为该委托定义
BeginInvoke 和 EndInvoke 方法。
BeginInvoke 方法可启动异步调用。它与您需要异步执行的方法具有相同的参数,另外它还有两个可选参数。第一个参数是一个 AsyncCallback
委托,该委托引用在异步调用完成时要调用的方法。第二个参数是一个用户定义的对象,该对象可向回调方法传递信息。BeginInvoke
立即返回,不等待异步调用完成。BeginInvoke 会返回 IAsyncResult,这个结果可用于监视异步调用进度。
EndInvoke 方法检索异步调用的结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;如果异步调用尚未完成,EndInvoke
将一直阻止调用线程,直到异步调用完成后才允许调用线程执行。EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数(在 Visual
Basic 中为 <Out> ByRef
和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。
本主题中的代码示例演示了四种使用 BeginInvoke 和 EndInvoke 进行异步调用的常用方法。调用 BeginInvoke
之后,您可以执行下列操作:
进行某些操作,然后调用 EndInvoke 一直阻止到调用完成。
使用 System.IAsyncResult.AsyncWaitHandle
属性获取 WaitHandle,使用它的
WaitOne
方法一直阻止执行直到发出 WaitHandle 信号,然后调用 EndInvoke。
轮询由 BeginInvoke 返回的 IAsyncResult,确定异步调用何时完成,然后调用 EndInvoke。
将用于回调方法的委托传递给 BeginInvoke。异步调用完成后,将在 ThreadPool
线程上执行该方法。该回调方法将调用 EndInvoke。
每次都要调用 EndInvoke 来完成异步调用。 |
定义测试方法和异步委托
下面的代码示例演示异步调用同一个长时间运行的方法TestMethod
的各种方式。
TestMethod
方法会显示一条控制台消息,说明它已开始处理,休眠了几秒钟,然后结束。
TestMethod有一个 out
参数,该参数用于演示此种参数添加到 BeginInvoke 和 EndInvoke 的签名中的方式。您可以按同样的方式处理 ref 参数。
下面的代码示例演示
TestMethod的定义和名为
AsyncMethodCaller
的、可用来异步调用
TestMethod的委托。若要编译任何代码示例,必须包括
TestMethod
的定义和
AsyncMethodCaller委托。
I |
C# | |
---|---|
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
会阻止它,所以不要从服务于用户界面的线程中调用它。
C# | |
---|---|
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 检索结果之前,还可以执行其他处理。
C# | |
---|---|
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 WaitHa 4000 ndle 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
线程上执行时继续执行。
C# | |
---|---|
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。
C# | |
---|---|
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); } } } |
相关文章推荐
- C#使用异步方式调用同步方法
- 使用异步方式调用同步方法
- 使用异步方式调用同步方法
- [转摘]使用异步方式调用同步方法
- 使用异步方式调用同步方法
- 使用异步方式调用同步方法(实例详解)
- 使用异步方式调用同步方法
- ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用!因此,ES transport client可以同步调用也可以异步(不过底层的socket必然是异步实现)
- VC++ .NET UI同步(使用Invoke托管方法),异步线程调用UI
- 用异步的方式调用同步方法
- 使用ASP.NET AJAX异步调用Web Service和页面中的类方法(10):服务器端和客户端数据类型的自动转换:以XML方式序列化数据、小结
- 用异步的方式调用同步方法
- 使用ASP.NET AJAX异步调用Web Service和页面中的类方法(10):服务器端和客户端数据类型的自动转换:以XML方式序列化数据、小结
- Android异步方法以同步方式实现
- javascript 异步调用 后台.cs里的方法 PageMethods如何使用
- 函数调用的几种方法 几种主流框架使用匿名函数模仿块级作用域的方式
- dhl:C#异步方法调用(使用委托,在委托上调用BeginInvoke方法)
- C# 异步编程 异步委托调用同步方法
- Android异步更新UI的方式之使用runOnUiThread(action)方法
- Ajax程序:处理异步调用中的异常(使用Asp.Net Ajax内建的异常处理方法)