ASP.NET 委托,异步调用例子 .

简要介绍:

1.定义异步执行需要调用的方法

2.定义具有与异步执行方法相同签名的委托(Delegate);

3.调用 BeginInvoke 和 EndInvoke 方法。

3.1. BeginInvoke 方法用于启动异步调用。它与需要异步执行的方法具有相同的参数,

只不过还有两个额外的参数。BeginInvoke 立即返回,不等待异步调用完成。

BeginInvoke 返回 IasyncResult,可用于监视调用进度。

3.2. EndInvoke 方法用于检索异步调用结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;

如果异步调用未完成,EndInvoke 将一直阻塞到异步调用完成。

EndInvoke 的参数包括需要异步执行的方法的 out 和 ref 参数以及由 BeginInvoke 返回的 IAsyncResult。

3.3.调用了 BeginInvoke 后,可以:

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

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

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

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

//具体代码如下:

using System;

using System.Threading;

//The example of using delegate

namespace DelegateCallAsynchronousMethods

{

class AsyncFileDelegate

{

/*

*这是需要异步执行的方法,COPY一个文件

*/

public void CopyFile(String fileName, out bool result)

{

Console.WriteLine("Move file "+fileName+"...");

for (int i = 0; i < 10; i++)

{

Thread.Sleep(200);

Console.WriteLine("Move file is running..." + i);

}

Console.WriteLine("Move file finished");

result = true;

}

/*

*定义COPY文件的委托,将来CopyFile方法就委托给它去异步执行

*/

public delegate void CopyFileDelegate(String fileName, out bool result);//Declare copy file delegate

static void Main()

{

bool result;

AsyncFileDelegate aa = new AsyncFileDelegate();

// 开始委托方法,以后都由copyFile这个变量来做事

CopyFileDelegate copyFile = new CopyFileDelegate(aa.CopyFile);

Console.WriteLine("[Main] Invoking the asynchronous "+" Copy file method");

//委托调用异步方法去执行

IAsyncResult iAR = copyFile.BeginInvoke("songlin.txt", out result, null, null);

// 主方法不用等待COPY FILE方法,继续自己的事情

Console.WriteLine("[Main] Doing other work");

for (int i = 0; i < 10; i++)

{

Thread.Sleep(200);

Console.WriteLine("[Main]MainMethod is running..."+i);

}

Console.WriteLine(" [Main] Waiting for file transformation to finish");

/* 主方法自己的事情做完,开始检查COPYFILE有没有完成。

* 使用它的 WaitOne 方法将执行一直等到发出 WaitHandle 信号,然后调用 EndInvoke。

* 注意:异步调用完成时会发出 WaitHandle 信号,可以通过WaitOne 来等待它*/

iAR.AsyncWaitHandle.WaitOne();

Console.WriteLine("[Main] Copy file finished, cleaning up");

/* EndInvoke 方法用于检索异步调用结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;

* 如果异步调用未完成,EndInvoke 将一直阻塞到异步调用完成。

*/

copyFile.EndInvoke(out result, iAR);

Console.WriteLine("[Main] The result is {0}", result);

Console.ReadLine();

}

};

}

下面是输出结果,可以看出copyfile方法和主方法是异步执行的。

----------------------------------------------------------------------------------------------

[Main] Invoking the asynchronous Copy file method

[Main] Doing other work

Move file songlin.txt...

[Main]MainMethod is running...0

Move file is running...0

[Main]MainMethod is running...1

Move file is running...1

[Main]MainMethod is running...2

Move file is running...2

[Main]MainMethod is running...3

Move file is running...3

[Main]MainMethod is running...4

Move file is running...4

[Main]MainMethod is running...5

Move file is running...5

[Main]MainMethod is running...6

Move file is running...6

[Main]MainMethod is running...7

Move file is running...7

[Main]MainMethod is running...8

Move file is running...8

[Main]MainMethod is running...9

[Main] Waiting for file transformation to finish

Move file is running...9

Move file finished

[Main] Copy file finished, cleaning up

[Main] The result is True

以下是代码例子,模拟了文件拷贝。每个文件的拷贝方法都是在异步方式下运行,同时主方法依然运行。

在主方法的最后会等待直到所有的异步方法执行完成。

namespace WindowsApplication2

{

public class AsyncFileCopy

{

//Declare copy file delegate, will use this to invoke real copy file method

public delegate string CopyFileDelegate(int fileSize);

//The real file copy method, we simulate file copy with thread sleep

public String CopyFile(int fileSize)

{

switch (fileSize)

{

case 1:

Console.WriteLine("File 1 copy start...");

Thread.Sleep(1000);

Console.WriteLine("File 1 copy finished");

return "One";

case 2:

Console.WriteLine("File 2 copy Start...");

Thread.Sleep(2000);

Console.WriteLine("File 2 copy Finished");

return "Two";

case 3:

Console.WriteLine("File 3 copy Start...");

Thread.Sleep(3000);

Console.WriteLine("File 3 copy Finished");

return "Three";

default:

return "default";

}

}

public void ExecuteCopy()

{

List<WaitHandle> list = new List<WaitHandle>();

Console.WriteLine("Main method Start");

//Init coyp file delegate

CopyFileDelegate dlg = new CopyFileDelegate(CopyFile);

//Assume we have 4 different size files.

//Section below will let each file be copied in Async model

for (int i = 0; i < 4; i++)

{

//Let copy file executed in Async model, main thread continue

IAsyncResult ar = dlg.BeginInvoke(i, null, null);

list.Add(ar.AsyncWaitHandle);

Console.WriteLine("Main method still working" + i);

Thread.Sleep(10);//simulate main method cost some time

}

//Ensure all Async method finished before return from main method

System.Threading.WaitHandle.WaitAll(list.ToArray());

Console.WriteLine("Main method finished");

}

public static void Main(string[] args)

{

AsyncFileCopy test = new AsyncFileCopy();

test.ExecuteCopy();

}

}

}