在编写Windows Form应用程序时,为了实现界面的异步调用,有时经常需要将调用抛入线程池,然后在UI端进行同步的接收,已实现异步界面的异步调用效果。
但是因为异步调用参数集的不确定性和回调函数方法签名的难以识别性,有时为了实现很好的同步接收,需要引入弱类型的参数变量和返回值,但是弱类型,如果在代码中过多出现,就会造成代码的可读性、可维护性变弱,同时代码执行部分需要增加更多的类型判断和校验。
在.net中,提供了委托函数,可以直接对函数调用,进行指向,因为委托也是强类型的,如果全部采用命名委托来处理,则需要在代码中声明大量的委托。这虽然解决了函数指向和回调的问题,但是却造成了严重的代码膨胀。好在,在.net中提供了匿名委托函数,通过匿名委托函数,可以实现所有的方法签名的指向,这就解决了指向和代码膨胀的问题。
有了匿名委托,可以把函数的调用执行通过委托在异步线程处理,处理完毕后回调回同步线程,实现强类型和整齐调用的目的。
异步调用分三段,第一步声明发起操作,第二步,调度执行,第三步,界面同步显示,达到一致调用的目的。
示例代码:分页加载异步调用示例代码,根据查询数据,获取分页和每页需要显示的数据条数
public void DataLoad() { Func<Where, PageView, AsyncLoadResult<Depart>> beginDataLoad = new Func<Where, PageView, AsyncLoadResult<Depart>>(BeginDataLoad); object[] pa = new object[] { new Where(), this.PageView }; Action<AsyncLoadResult<Depart>> endDataLoad = new Action<AsyncLoadResult<Depart>>(EndDataLoad); BeginFunc(this, beginDataLoad, pa, endDataLoad); }
/// <summary> /// 异步加载调用 /// </summary> private AsyncLoadResult<Depart> BeginDataLoad(Where where, PageView pageView) { if (IsFirstLoad == true) { this.AsyncSyncDataCacheInit(); } int pageItemsCount = getProxy().Count(new Where[] { where }); List<IClause> clause = new List<IClause>(); clause.Add(where); if (orderBy != null && orderBy.Count > 0) { clause.Add(orderBy); } DataCollection<Depart> collection = getProxy().FindPage(1, pageView.PageSize, clause.ToArray()); pageView.PageItemsCount = pageItemsCount; pageView.IClause = clause; AsyncLoadResult<Depart> result = new AsyncLoadResult<Depart>(); result.ResultCollection = collection; result.PageView = pageView; return result; }
/// <summary> /// 同步界面显示 /// </summary> /// <param name="result"></param> private void EndDataLoad(AsyncLoadResult<Depart> result) { if (IsFirstLoad == true) { EES.Controls.Win.Config.Grid gridConfig = ViewGridConfig.GetByBindingDataType<Depart>(); this.DataBind(gridConfig); IsFirstLoad = false; } this.Input = result.ResultCollection; this.PageView = result.PageView; }