以用3种不同的方式处理异步命令。一种方式是启动异步进程,再选择 IAsyncResult对象,看看进程何时完成。第二种方式是在开始异步进程时提供一个回调方法。这种方式可以并行执行其他任务。异步进程完成时,就触发回调方法进行清理,并通知程序的其他部分该异步进程已完成。第三种也是最好的方法就是把一个等待句柄关联到异步进程上,使用这种方式,可以启动需要的所有异步进程,等待全部或部分进程的完成,以便对它们进行相应的处理。
Poll方式
view source print?
using System.Data.SqlClient;
|
using SYstem.Configuration;
|
protocted void Page_Load(object sender,EventArgs e)
|
SqlCommand Command = new SqlCommand();
|
SqlDataAdapter OrderReader;
|
IAsyncResult AsyncResult;
|
DBCon = new SqlConnection();
|
DBCon.ConnectionString = ConfigurationManger.ConnectionStrings["AspNetProvider"];
|
Command.CommandText = "SELECT TOP 5 Customers.*,Orders.* FROM Orders,Customers WHERE Orders.CustomerID = Customers.CustomerID ORDER BY ustomers.CompanyName";
|
Command.CommandType = CommandType.Text;
|
Command.Connection = DBCon;
|
AsyncResult = Command.BeginExecuteReader();
|
while(!AsyncResult.IsCompleted)
|
System.Threading.Thread.Sleep(10);
|
OrderReader = Command.EndExecuteReader(AsyncResult);
|
// To do Anything You Want
|
它首先调用BeginExecuteReader,启动异步进程。之后,使用while循环等待进程的完成。在等待时,主线程全检查异步进程的状态,然后休眠10毫秒。进程完成后,就使用EndExecuteReader方法提取结果。
如果在while循环上设置一个断点,就可以看到代码在调用BeiginExecuteReader方法后会继续执行。之后代码继续循环,直到异步进程完成为止。
Wait方式
3种方式中最好的一种不是Poll方式,也不是回调方式,而是Wait方式。该方式提供的灵活性最大、效率最高,但有点复杂。使用这种方式,可以编写代码,启动多个异步进程,等待全部或部分进程的完成。这种方式允许只等待互相依赖的进程,然后继续执行不互相依赖的进程。按照其设计,这种方式需要仔细考虑异步进程。必须认真选择出以并行方式运行的异步进程,最重要的是,确定不同的进程如何相互依赖。这种方式的复杂性在于,需要理解其中的细节,并设计出相应的代码。最终结果一般是,非常简洁的代码设计能最大限度地利用同步和异步处理模型。
view source print?
using System.Data.SqlClient;
|
using System.Data.Configuration;
|
protected void Page_Load(object sender,EventArgs e)
|
SqlCommand Command = new SqlCommand();
|
SqlDataReader OrdersReader;
|
IAsyncResult AsyncResult;
|
System.Threading.WaitHandle WHandle;
|
DBCon = new SqlConnection();
|
DB.ConnectionStrings = ConfigurationManager.ConnectionStrings["AspNetProvider"];
|
Command.CommandText = "SELECT TOP 5 Customers.*,Orders.* FROM Orders,Customers WHERE Orders.CustomerID = Customers.CustomerID ORDER BY ustomers.CompanyName";
|
Command.CommandType = CommandType.Text;
|
Command.Connection = DBCon;
|
AsyncResult = Command.BeginExecuteReader();
|
WHandle = AsyncResult.AsyncWaitHandle;
|
if(WHandle.WaitOne() == true)
|
OrdersReader = Command.EndExecuteReader(AsyncResult);
|
// When Execute On Timeouts EventHandler
|
<P>如果设置一个断点,单步执行这段代码,程序就会在WHandle.WaitOne方法调用处停止执行。在异步进程完成后,程序会自动恢复执行。</P><P><BR><STRONG>回调方式</STRONG><BR>它首先调用BeginExecuteReader方法,给它传送回调委托,以启动异步进程。不需要进一步的处理,该方法在异步进程启动后结束。触发回调委托,以启动异步进程。不需要进一步的处理,该方法在异步进程启动后结束。</P>
|
view source print?
<PRE class=brush:csharp;gutter:false;>public class SampleClass
|
protected void Page_Load(object sender,EventArgs e)
|
SqlCommand Command = new SqlCommand();
|
SqlDataReader OrdersReader;
|
IAsyncResult AsyncResult;
|
DBCon = new SqlConnection();
|
DB.ConnectionStrings = ConfigurationManager.ConnectionStrings["AspNetProvider"];
|
Command.CommandText = "SELECT TOP 5 Customers.*,Orders.* FROM Orders,Customers WHERE Orders.CustomerID = Customers.CustomerID ORDER BY ustomers.CompanyName";
|
Command.CommandType = CommandType.Text;
|
Command.Connection = DBCon;
|
AsyncResult = Command.BeginExecuteReader(new AsyncCallback(CBMethod),CommandBehavior.CloseConnection);
|
public void CBMethod(SQLAsyncResult ar)
|
SqlDataReader OrdersReader;;
|
OrdersReader = ar.EndExecuteReader(ar);
|
<P>回调方式可以在代码的另一个部分处理命令执行的结果。当命令执行的时间比较长,且需要在不待到命令执行完毕后就回应用户时,可以使用这种方式。</P>
|
<P><STRONG>取消异步处理<BR></STRONG>异步进程需要的时间常常比希望的长。为了避免这个问题,可以给用户提供一个选项来取消该进程,而不等待结果。取消异步进程只需在相应的Command对象上调用Cancel方法即可。这个方法没有返回值。为了回退已由Command对象完成的工作,必须在执行查询前,给Command对象提供一个定制事务。也可以自己处理回退或提交进程。</P>
|