C# WPF中事件处理时如何持续显示动画直到数据库查询完成
问题根因
- WPF的动画渲染、UI交互全部依赖UI线程调度,你现有代码中的数据库查询逻辑直接运行在UI线程,耗时的IO操作阻塞了UI线程,直接导致动画停摆
- 你额外开线程又用
Dispatcher.Invoke切回UI线程启动动画的操作完全冗余,没有解决核心的查询阻塞UI问题 - 原有动画默认只执行一次,没有设置循环播放,也会导致动画提前结束
修改后的XAML代码
给动画添加永久循环属性,保证启动后持续转动直到手动停止:
<Window.Resources> <Storyboard x:Key="RotationBtn" RepeatBehavior="Forever"> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="Command4"> <EasingDoubleKeyFrame KeyTime="0:0:1" Value="720"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </Window.Resources> <!-- 其余XAML代码无需修改 -->
修改后的C#代码
使用异步方案把数据库查询放到后台线程执行,完全不阻塞UI线程的动画渲染:
// 提前引入所需命名空间 using System.Data.Entity; using System.Threading.Tasks; private async void Command4_Click(object sender, RoutedEventArgs e) { // UI线程启动动画,无阻塞 Storyboard sb = TryFindResource("RotationBtn") as Storyboard; Storyboard.SetTarget(sb, Command4); sb.Begin(); // 异步执行数据库查询,自动调度到后台线程,不卡UI var MyQuery = await dbms.Database.SqlQuery<DB_Cust>("SELECT * FROM Customers").ToListAsync(); // 查询完成后停止动画,不需要停止可注释该行 sb.Stop(); // 后续对查询结果的业务逻辑写在这里,await会自动切回UI线程,可直接操作界面控件 }
兼容旧版本EF的替代方案
如果你用的Entity Framework版本不支持ToListAsync异步方法,可以用Task.Run包裹同步查询实现同样效果:
private async void Command4_Click(object sender, RoutedEventArgs e) { Storyboard sb = TryFindResource("RotationBtn") as Storyboard; Storyboard.SetTarget(sb, Command4); sb.Begin(); // 把同步查询放到后台线程执行 var MyQuery = await Task.Run(() => { return dbms.Database.SqlQuery<DB_Cust>("SELECT * FROM Customers").ToList(); }); sb.Stop(); }
内容的提问来源于stack exchange,提问作者user15232953
相关产品推荐
相关产品推荐

