WPF非UI线程访问网络资源造成页面假死现象
公司内部一个项目是用WPF作为GUI 访问web接口的形式获取数据,
但是由于数据量比较大,也没做分页,于是就需要一个loading的控件,网上查了很多资料但都比较浅。这里完成需求后,总结一下。
首先。loading控件的实现基本上都是1.控件显示;2.后台访问查询;3.UI渲染;4.控件隐藏。
想要实现这部分,需要做到异步,这里使用BackgroundWorker 组件用来执行诸如数据库事务、文件下载等耗时的异步操作。
关于backgroundWorker这里不做过多的记录,已经有很多人进行了系统的用法归类,这里仅仅使用其以下方法:
1.BackgroundWorker bgMeet = new BackgroundWorker(); //创建对象
2.bgMeet.WorkerReportsProgress = true; //为了显示后台操作的执行进度,一般使用进度条时可以用其配套的ReportProgress()方法,通过它传递操作完成的进度值,此外,该方法触发ProgressChanged事件,在是此事件中,通过ProgressChangedEventArgs的实例,接收到主线程传递过来的参数。
3.bgMeet.DoWork += new DoWorkEventHandler(bgMeet_DoWork);//后台需要做的
4.bgMeet.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgMeet_RunWorkerCompleted);//完成后,反馈
下面是dowork方法:
1.loading控件显示
this.Dispatcher.Invoke(DispatcherPriority.Background,new Action(() =>
{
this.loading.Visibility = Visibility.Visible;
}));//这里需要用dispatcher.invoke 因为WPF却明确的规定:UI元素只能由其主线程来操作
2.从接口获取数据 getData();//这里访问接口不能用dispatcher.invoke 否则会造成页面假死现象 因为子线程去访问时,由于时间长,会造成UI卡住
3.渲染数据
下面是completed方法:隐藏loading控件
void bgMeet_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
{
this.loading.Visibility = Visibility.Collapsed;
}));
}