C#异步调用方法总结

来源:互联网 发布:女士秋季新款服装淘宝 编辑:程序博客网 时间:2024/06/11 17:56

示例 1: 同步调用的方法此示例演示如何通过使用 MethodDelegate委托同步调用 LongRunningMethod() 。其他示例对比这通过以异步方式进行调用。 启动 Microsoft VisualStudio.net Microsoft Visual Studio 2005。 创建一个名为 AsyncDemo 的新的 Visual C# 控制台应用程序项目。 添加一个名为 AsyncDemo 到项目中,新的.cs 文件如下定义的类:

 using System;
using System.Threading ;
using System.Windows.Forms ;
public class AsyncDemo
{
    string LongRunningMethod (intiCallTime, 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()
    {   strings ;
       int iExecThread;
       // Create an instance of a delegatethat wraps LongRunningMethod.  MethodDelegatedlgt = new MethodDelegate (this.LongRunningMethod) ;  
    // Call LongRunningMethod using thedelegate.
       s = dlgt(3000, outiExecThread); 
       MessageBox.Show (string.Format("The delegate call returned the string:  /"{0}/",                                     and thethread 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 = newMethodDelegate (this.LongRunningMethod) ;
   string s ;
int iExecThread;

    // Initiate the asynchronous call.
    IAsyncResult ar = dlgt.BeginInvoke(3000,out iExecThread, null, null); 
    // Do some useful work here. Thiswould be work you want to have
    // run at the same time as theasynchronous call.
    // Retrieve the results of the asynchronouscall.
    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 = newMethodDelegate (this.LongRunningMethod) ;

    // Initiate the asynchronous call.
    IAsyncResult ar =dlgt.BeginInvoke(3000, out iExecThread, null, null);

    // Do some useful work here. Thiswould be work you want to have
    // run at the same time as theasynchronous call.
    // Wait for the WaitHandle to becomesignaled.

    ar.AsyncWaitHandle.WaitOne() ;

    // Get the results of the asynchronouscall.

    s = dlgt.EndInvoke (out iExecThread,ar) ;

    MessageBox.Show (string.Format("The delegate call returned the string:  /"{0}/",
                                 and thenumber {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 = newAsyncCallback(MyAsyncCallback);

    // Initiate the Asynchronous call passingin the callback delegate
    // and the delegate object used toinitiate the call.
    IAsyncResult ar = dlgt.BeginInvoke(3000,out iExecThread, cb, dlgt);
}
public void MyAsyncCallback(IAsyncResult ar)
{
    string s ;
int iExecThread ;
    // Because you passed your originaldelegate in the asyncState parameter
    // of the Begin call, you can get itback 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 运行应用程序。

原创粉丝点击