用delegate实现.NET应用程序的同步函数的异步调用-.NET多线程编程实践之一
在C++中有2种类型的线程:UI Thread和Worker Thread,前者是基于用户界面的有消息循环的线程、后者是没有用户界面的侧重于大时空运算的线程。直接调用Windows相关线程及同步对象的API即可。
在.NET framework进阶编程中,可以用基于delegate的方式来处理界面保持活动,而后台作大运算量或耗时的操作。
应用程序的需求是:点击一个按钮来刷新用户界面上某区域数据相关控件,其内容动态从web service上获取并填充到该控件,而不影响另一区域实时显示数据。
关键代码段如下:
private void UpdateInquiry(){//UI界面的更新放在这里(the other thread)//control operations on GUI such as clear, load data, fresh etc. ...} private delegate void crossThreadDelegate(); private void UpdateInquiryContainer()//此函数也可用于同步调用 { //耗时操作一定要放在这里,不要包含在UpdateInquiry(UI界面的更新)中!!!(just like a worker thread as windows API) this._presenter.TimeConsumingOperation(); if (treeListInquired.InvokeRequired) { crossThreadDelegate caller = new crossThreadDelegate(UpdateInquiry); treeListInquired.Invoke(caller); } else { UpdateInquiry(); } } //callback function which is used to end the asynchronous inquiry operation and resume the //enable state of related controls public void AsyncRefreshCallback(IAsyncResult result) { AsyncRefreshCaller inquiryDelegate = (AsyncRefreshCaller)((AsyncResult)result).AsyncDelegate; inquiryDelegate.EndInvoke(result); //enable related controls again - there may be an issue thread-safe-related - by OY if (bCanDemand) { dateTimePickerDate.Enabled = true; btnPrev.Enabled = true; btnNext.Enabled = true; btnRefresh.Enabled = true; } } private delegate void AsyncRefreshCaller(); private void RefreshInquiry() { //disable related controls on GUI dateTimePickerDate.Enabled = false; btnPrev.Enabled = false; btnNext.Enabled = false; btnRefresh.Enabled = false; //invoke synchronous method asynchronously AsyncRefreshCaller inquiryDelegate = new AsyncRefreshCaller(UpdateInquiryContainer); AsyncCallback callback = new AsyncCallback(this.AsyncRefreshCallback); inquiryDelegate.BeginInvoke(callback, null); //inquiryDelegate.BeginInvoke(null, null); }