如何以异步方式调用的 Visual C# 方法

 我来答
ぷツb78
2013-10-25 · 超过60用户采纳过TA的回答
知道答主
回答量:99
采纳率:0%
帮助的人:137万
展开全部
以异步方式调用的函数会导致系统调用的函数继续进行其他工作的同时在后台辅助线程上执行它们。在典型 (同步) 函数的调用该函数上相同的线程进行调用的立即执行。调用函数等待调用完成,并接收在继续之前调用的结果。通过与之相反时进行异步调用,您检索异步调用以后的结果。本文演示如何使用 Visual C# 执行此操作。 要求下面的列表概述了建议的硬件、 软件、 网络的基础结构和所需的服务包: Microsoft Windows 2000 或 Windows XP 或 Windows Server 2003visual Studio.net 或 Visual Studio 2005本文假定您熟悉下列主题: 调用的方法在 Visual C# 中如何使用委托如何生成异步调用通过使用委托进行异步调用。委托是包装函数的对象。委托提供同步功能,并且还提供方法以异步方式调用将被包装的函数。这些方法为 BeginInvoke() 和EndInvoke()。根据委托包装的函数的签名不同,这些方法的参数列表也会有所不同。请注意,Visual Studio.net 智能感知功能不会显示 BeginInvoke() 和EndInvoke(),因此看不到它们出现在该函数列出了您键入时。 BeginInvoke() 用于启动异步调用。它具有相同的参数作为该包装函数以及将在本文内下文中描述的两个附加参数。BeginInvoke() 立即返回,并不会等待异步调用完成。BeginInvoke() 返回IAsyncResult 对象。 EndInvoke() 函数用于检索异步调用的结果。可以随时在 BeginInvoke() 后对其进行调用。如果异步调用未完成还,EndInvoke() 块直到它完成。EndInvoke() 函数的参数包括在 out 和ref 参数的被包装的函数具有,以及由 BeginInvoke() 返回该 IAsyncResult 对象。 下面是一个委托和其 BeginInvoke() 和EndInvoke() 方法的示例: // The following delegate delegate string MethodDelegate(int iCallTime, out int iExecThread) ; // will have the following BeginInvoke() and EndInvoke methods: IAsyncResult MethodDelegate.BeginInvoke(int iCallTime, out int iExecThread, AsyncCallback cb, object AsyncState); string MethodDelegate.EndInvoke (out int iExecThread, IAsyncResult ar) ; 有四个常见的方式,可使用 BeginInvoke() 和EndInvoke() 来进行异步调用。调用 BeginInvoke() 后,您可以: 还可以执行一些其他操作,然后使用 EndInvoke()。获取由 IAsyncResult 对象提供一个 WaitHandle、 使用其 WaitOne 方法将阻塞,直到 WaitHandle 处于终止状态,然后调用 EndInvoke()。轮询以确定完成异步调用后,然后调用 EndInvoke()IAsyncResult 对象。使系统在调用指定的回调函数。 此回调函数调用 EndInvoke() 并完成时处理异步调用的结果。下面的代码示例演示这些调用模式,通过使用下面的函数进行同步调用对它们进行对比: string LongRunningMethod (int iCallTime, out int iExecThread) { Thread.Sleep (iCallTime) ; iExecThread = AppDomain.GetCurrentThreadId (); return "MyCallTime was " + iCallTime.ToString() ; } LongRunningMethod() 模拟通过休眠长时间运行的函数。它将返回休眠时间和执行它的线程的 ID。如果您调用其异步,就会发现正在执行的线程的线程 ID 是不同的调用线程。 第一步是定义的函数委托: delegate string MethodDelegate(int iCallTime, out int iExecThread) ; 示例1: 同步调用的方法此示例演示如何通过使用 MethodDelegate 委托同步调用 LongRunningMethod()。其他示例对比这通过以异步方式进行调用。 启动Microsoft Visual Studio.net 或 Microsoft Visual Studio 2005。创建一个名为 AsyncDemo 的新的 Visual C# 控制台应用程序项目。添加一个名为 AsyncDemo 到项目中,新的.cs 文件如下定义的类: using System; using System.Threading ; using System.Windows.Forms ; public class AsyncDemo { string LongRunningMethod (int iCallTime, out int iExecThread) { Thread.Sleep (iCallTime) ; iExecThread = AppDomain.GetCurrentThreadId (); return "MyCallTime was " + iCallTime.ToString() ; } delegate string MethodDelegate(int iCallTime, out int iExecThread) ; public void DemoSyncCall() { string s ; int iExecThread; // Create an instance of a delegate that wraps LongRunningMethod. MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ; // Call LongRunningMethod using the delegate. s = dlgt(3000, out iExecThread); MessageBox.Show (string.Format ("The delegate call returned the string: \"{0}\", and the thread ID {1}", s, iExecThread.ToString() ) ); } } 以后,此类演示如何进行异步调用。 最初,但是,它只包含演示如何同步调用该委托将 DemoSyncCall() 方法。在Visual Studio 自动创建在您的项目中的 Main 函数的正文中添加以下代码: static void Main(string[] args) { AsyncDemo ad = new AsyncDemo () ; ad.DemoSyncCall() ; } 按CTRL + F5 运行应用程序。示例2: 将调用一个方法异步使用 EndInvoke() 呼叫图案在这一节中示例异步调用相同的方法。调用模式使用的是调用 BeginInvoke,做一些工作在主线程上,然后调用 EndInvoke()。请注意 EndInvoke() 才会返回到异步调用已完成。此调用模式非常有用时要调用的线程正在执行异步调用的同时执行工作。有工作发生在同一时间可以提高很多应用程序的性能。若要以这种方式以异步方式运行的常见任务是文件或网络操作。 添加命名 DemoEndInvoke()AsyncDemo 类方法。DemoEndInvoke 函数演示如何以异步方式调用该委托。 public void DemoEndInvoke() { MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ; string s ; int iExecThread; // Initiate the asynchronous call. IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, null, null); // Do some useful work here. This would be work you want to have // run at the same time as the asynchronous call. // Retrieve the results of the asynchronous call. s = dlgt.EndInvoke (out iExecThread, ar) ; MessageBox.Show (string.Format ("The delegate call returned the string: \"{0}\", and the number {1}", s, iExecThread.ToString() ) ); } 对于主 编辑源代码,这样它就会包含下面的代码: static void Main(string[] args) { AsyncDemo ad = new AsyncDemo () ; ad.DemoEndInvoke() ; } 按CTRL + F5 运行应用程序。示例3: 异步调用的方法和使用要等待的呼叫的 A WaitHandle 为完成在这一节中此示例异步调用该方法,并等待一个 WaitHandle,它调用 EndInvoke() 之前。由 BeginInvoke() 返回该 IAsyncResult 都有一个 AsyncWaitHandle 属性。此属性返回当异步调用完成时终止的 WaitHandle。正在等待一个 WaitHandle 是常用的线程同步技术。调用线程将等待 WaitHandle 使用WaitHandleWaitOne() 方法。WaitOne() 块直到 WaitHandle 处于终止状态。返回 WaitOne(),您可以执行一些额外的工作在调用 EndInvoke() 之前。在上面的示例中为这种方法可用于执行调用的主线程,否则将阻止的文件或 $ 网络操作。 添加命名 DemoWaitHandle()AsyncDemo 类函数。DemoWaitHandle() 函数演示如何以异步方式调用该委托。 public void DemoWaitHandle () { string s ; int iExecThread; MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ; // Initiate the asynchronous call. IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, null, null); // Do some useful work here. This would be work you want to have // run at the same time as the asynchronous call. // Wait for the WaitHandle to become signaled. ar.AsyncWaitHandle.WaitOne() ; // Get the results of the asynchronous call. s = dlgt.EndInvoke (out iExecThread, ar) ; MessageBox.Show (string.Format ("The delegate call returned the string: \"{0}\", and the number {1}", s, iExecThread.ToString() ) ); } 对于主 编辑源代码,这样它就会包含下面的代码: static void Main(string[] args) { AsyncDemo ad = new AsyncDemo () ; ad.DemoWaitHandle () ; } 按CTRL + F5 运行应用程序。示例4: 将调用一个方法异步使用轮询呼叫图案在这一节中示例轮询 IAsyncResult 对象,了解何时异步调用已完成。所返回 BeginInvoke()IAsyncResult 对象都有一个 IsCompleted 属性异步调用完成后返回 True。然后,您可以调用 EndInvoke()。此调用模式是很有用,如果您的应用程序正在进行的工作要有长时间运行的函数被阻止。Microsoft Windows 应用程序是一个这样的示例。在 Windows 应用程序的主线程可以继续处理用户输入,执行一个异步调用时。它可以定期检查 IsCompleted 以查看是否已完成呼叫。它将调用 EndInvoke 时IsCompleted,则 返回true。因为 EndInvoke() 阻止异步操作完成之前,应用程序不调用它知道已完成的操作之前。 添加命名 DemoPolling()AsyncDemo 类函数。DemoPolling() 函数演示如何以异步方式调用该委托,并使用轮询查看进程是否完整。 public void DemoPolling() { MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ; string s ; int iExecThread; // Initiate the asynchronous call. IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, null, null); // Poll IAsyncResult.IsCompleted while(ar.IsCompleted == false) { Thread.Sleep (10) ; // pretend to so some useful work } s = dlgt.EndInvoke (out iExecThread, ar) ; MessageBox.Show (string.Format ("The delegate call returned the string: \"{0}\", and the number {1}", s, iExecThread.ToString() ) ); } 主 编辑源代码。该函数的内容替换为以下代码: static void Main(string[] args) { AsyncDemo ad = new AsyncDemo () ; ad.DemoPolling () ; } 按CTRL + F5 运行应用程序。示例5: 一种异步方法完成时执行回叫在这一节中该示例提供了一个回调委托到 BeginInvoke() 函数的系统执行异步调用完成时。回调调用 EndInvoke() 并处理异步调用的结果。此调用模式是很有用,如果启动异步调用的线程不需要处理调用的结果。异步调用完成时,系统将调用回调发起的线程以外的其他线程上。 若要用于此调用模式您必须作为 BeginInvoke() 函数的倒数第二个参数传递类型 AsyncCallback 的委托,该委托。BeginInvoke() 还有最后一个参数的类型 对象,您可以将任何对象传递到其中。当调用时,该对象是可用于您的回调函数。为此参数的一个重要用途是将传递用于启动该调用该委托。回调函数然后可以使用该委托的 EndInvoke() 功能来完成调用。下面演示了此调用模式。 添加命名 DemoCallback() 和MyAsyncCallback()AsyncDemo 类的两种方法。DemoCallback() 方法演示如何以异步方式调用该委托。它使用委托来包装系统调用异步操作完成时在 MyAsyncCallback() 方法。MyAsyncCallback() 调用EndInvoke()。 public void DemoCallback() { MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ; string s ; int iExecThread; // Create the callback delegate. AsyncCallback cb = new AsyncCallback(MyAsyncCallback); // Initiate the Asynchronous call passing in the callback delegate // and the delegate object used to initiate the call. IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, cb, dlgt); } public void MyAsyncCallback(IAsyncResult ar) { string s ; int iExecThread ; // Because you passed your original delegate in the asyncState parameter // of the Begin call, you can get it back here to complete the call. MethodDelegate dlgt = (MethodDelegate) ar.AsyncState; // Complete the call. s = dlgt.EndInvoke (out iExecThread, ar) ; MessageBox.Show (string.Format ("The delegate call returned the string: \"{0}\", and the number {1}", s, iExecThread.ToString() ) ); } 主 编辑源代码。该函数的内容替换为以下代码: 回到顶端 | 提供反馈
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式