| | | .NET Framework 精简版后台处理技术 | | 2003-05-10·
· ··Mirosoft
| 上一页 1 2 3 4 下一页 通知
大多数情况下,通知是最佳选择,因为它允许应用程序启动对 Web 服务的调用,然后不需要任何特殊处理即可继续进行。Web 服务启动后,应用程序向“Begin”方法传递一个 AsyncCallback 委托。Web 服务调用完成后,将自动调用该委托。使用通知时,不需要存储“Begin”方法返回的 IAsyncResult,因为它将作为参数自动传递给通知委托。
class MyCalcForm : Form { private MathProxy _wsMath = new MathProxy(); public int _sum; public void btnAdd_OnClick(object sender, EventArgs e) { AsyncCallback cb = new AsyncCallback(OnAddComplete); _wsMath.BeginAdd(10, 15, cb, null); // 初始化 XML Web Service 调用 } public OnAddComplete(IAsyncResult ar) // 完成后由框架调用 { _sum = _wsMath.EndAdd(ar); // 获取 XML Web Service 结果 } | 警告:委托调用的方法在后台线程而不是主应用程序线程中运行。因此,委托方法无法安全地影响用户界面。有关详细信息,请参阅本文后面的“后台处理和用户体验”一节。
中断
有些情况下,应用程序在返回 Web 服务结果之前,只能执行一部分工作。在这种情况下,最好是先启动 Web 服务,执行工作中不依赖于 Web 服务结果的部分,然后中断,等待 Web 服务完成。IAsyncResult.AsyncWaitHandle 即提供了此功能。Web 服务调用启动后,AsyncWaitHandle 处于未收到信号状态,当 Web 服务调用完成后,AsyncWaitHandle 将收到信号。使用 AsyncWaitHandle 中的 WaitOne 方法会导致调用线程(通常为主应用程序线程)中断,直到 Web 服务完成。
public void DoCalculations() { IAsyncResult ar = _wsMath.BeginAdd(10, 15, null, null); // 执行不需要 Add(添加)操作结果的工作 ar.AsyncWaitHandle.WaitOne() ; // 中断,直到调用完成 int sum = _wsMath.EndAdd(ar) ; // 检索结果 // 继续处理 } | 轮询
少数情况下,应用程序可能希望一边进行处理,一边周期性地检查 Web 服务调用。使用 IAsyncResult.IsCompleted,应用程序可以确定 Web 服务调用是否完成。
IAsyncResult ar = _wsMath.BeginAdd(10, 15, null, null); While (! ar.IsCompleted) // 循环,直到调用完成 { // 等待时执行其他工作 } int sum = _wsMath.EndAdd(ar) ; // 检索结果 | 线程池
当应用程序需要执行长时间运行的本地进程(例如很长的计算、文件处理或初始化)时,可以利用 .NET Framework 精简版提供的内置线程池。线程池允许在后台运行多个工作,而不需要为每个任务频繁地创建和销毁单独的线程,从而减少了开销。
.NET Framework 精简版线程池通过 ThreadPool 类提供。通过将一个方法打包到 WaitCallback 委托中,然后将该委托传递给 ThreadPool.QueueUserWorkItem 静态方法,在线程池中对任务进行排队。
void ReadBigFile(object val) { // 执行读取和处理文件的操作 }
public void btnStartRead_Click(object sender, EventArgs e) { // 将 ReadBigFile 打包到委托中并提交给线程池 WaitCallback w = new WaitCallback(ReadBigFile) ; ThreadPool.QueueUserWorkItem(w) ; } | 在上面的示例中,ReadBigFile 方法将在线程池中排队并在一个可用的线程上运行。对 QueueUserWorkItem 的调用将中断,直到将请求放入队列中。
当要向后台进程传递参数时,QueueUserWorkItem 将提供一个重载,该重载接受一个附加参数,然后将其传递给已排队的方法。该参数被定义为对象,因而可以传递任何类型的参数。
void ReadBigFile2(object val) { string dataFile = (string) val ; // val 是对 fName 的引用 // 执行读取和处理 dataFile 的操作 }
public void btnStartRead_Click(object sender, EventArgs e) { string fName = "BigDataFile.xml" ; WaitCallback w = new WaitCallback(ReadBigFile2) ; // fName 将被传递给 ReadBigFile ThreadPool.QueueUserWorkItem(w, fName) ; } |
上一页 1 2 3 4 下一页 | | | 感谢
访问天极网,如果您觉得该文章涉及版权问题,请看这里!
|
|