C#异步调用方法总结

示例 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 使用 WaitHandle WaitOne() 方法。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 () ;

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

编辑源代码。该函数的内容替换为以下代码:

  static void Main(string[] args)
{
    AsyncDemo ad = new AsyncDemo () ;
    ad.DemoCallback() ;
}

CTRL + F5 运行应用程序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值