前言:以前使用数据库搜数据后直接传到前台设置,后来学会了绑定,界面结合部分总算是有了点经验,But....有时候搜数据没那么快,要等待数据返回的时候界面假死,白屏,很崩溃,后来使用了几种方法 :1.延迟加载先出来界面,在赋值数据 ,2.利用多线程加载,但是一开始的时候会是空白(可以预先初始化来解决),然后搭配complate事件;3.逻辑控制,就是自己想一些办法让程序看起来是正常的,比如加载页,延时,锁死等..;
然而:我今天要讲的是异步加载,并且包含绑定部分的代码;
下面这一部分是 在一个汇总类(class)里 需要收集 值的方法 并且在每一个属性值赋值的时候通知前台页面改变
如果不需要报告进度 一段一段显示 可以直接等最终结果;
不说了上代码;
public async Task MyMethodAsync(IProgress<TaskCallBackValue> progress)
{
TaskCallBackValue percentCompleate = new TaskCallBackValue();
if (progress == null)
{
throw new Exception("必须实现报告进度方法!");
}
await Task.Delay(TimeSpan.FromSeconds(3));//模拟卡顿效果
Task<int> T1 = SugarBase.DB.Queryable<property_house_info>().CountAsync(x => x.take_effect != 2);
progress.Report(new TaskCallBackValue { Name = "TotalHouseNumber", Value = T1.Result });
await Task.Delay(TimeSpan.FromSeconds(2));//模拟卡顿效果
Task<int> T2 = SugarBase.DB.Queryable<property_house_info>().CountAsync(x => x.take_effect == 0);
progress.Report(new TaskCallBackValue { Name = "TotalInuseHouseNumber", Value = T2.Result });
}
public class TaskCallBackValue
{
public string Name { get; set; }
public object Value { get; set; }
}
这一段 其实有点类似 BackgroundWork 里的ProgressChanged 事件 这是第一个部分
那么在页面搜索方法中少不了 this.DataContext =this 这样的绑定
《textBlock text{binding Youdata.Data1}.....
《textBlock text{binding Youdata.Data2}.....
public void CallMyMethodAsync()
{
var progress = new Progress<TaskCallBackValue>();
progress.ProgressChanged += (sender, e) =>
{
Type t = typeof(HomeSummary);
var Pr = t.GetProperty(e.Name);
if (Pr != null)
{
Pr.SetValue(CurrentSummaryData, e.Value, null);
//CurrentSummaryData.OnChange(e.Name);//本来想开放PropertyChange事件没想到居然不需要也能触发界面刷新
}
};
MyMethodAsync(progress);
}
这个地方就要说一说了,我传出来的是属性名称 和属性的值,但是总不能 class.name1=value ;class.name2=value 这样赋值
所以找了反射的代码利用PropertyInfo的方法给我的汇总类里面的属性赋值 这样 从小方法里发回的异步通知就具有了通用性
在前台的效果是 预设界面直接显示无卡顿, 两个TextBlock的值 分别是第3秒和第5秒显示在了界面上
值的提到的是 这个方法里如果有一个出现了 错误那么整个方法都会异常,所以做好异常处理是很有必要的
并且 不能在主线程里await 可能会出现主线程屏蔽初始化,一点界面都没有
综上综上 只是为了 一进界面不卡而已。
方法摘自 :《C#并发编程经典实例》