在MainWindow中,我有 <ListOfData>
<ListOfP>
<First_Name>F1</First_Name>
<Last_Name>L1</Last_Name>
<PaySlip>
<PaySlip_Val>y</PaySlip_Val>
<ListOfPaySlipMonth>
<ListOfPaySlipData>
<Month>Jan</Month>
<Salary>$$$</Salary>
<Year>2016</Year>
</ListOfPaySlipData>
<ListOfPaySlipData>
<Month>Feb</Month>
<Salary>$$$</Salary>
<Year>2016</Year>
</ListOfPaySlipData>
<ListOfPaySlipData>
<Month>Mar</Month>
<Salary>$$$</Salary>
<Year>2016</Year>
</ListOfPaySlipData>
<ListOfPaySlipData>
<Month>Apr</Month>
<Salary>$$$</Salary>
<Year>2016</Year>
</ListOfPaySlipData>
</ListOfPaySlipMonth>
</PaySlip>
</ListOfP>
</ListOfData>
方法,显示忙指标
async
加载面板如下:
public async Task BusyLoaderAsync(Action doWorkAction)
{
using (var tokenSource = new CancellationTokenSource())
{
await loadingPanel.StartSpinAsync(tokenSource.Token).ConfigureAwait(false);
await this.Dispatcher.InvokeAsync(doWorkAction);
tokenSource.Cancel();
await loadingPanel.StopSpinAsync().ConfigureAwait(false);
}
}
控制加载面板还有两种方法:
<Grid Panel.ZIndex="1000" HorizontalAlignment="Stretch" Grid.RowSpan="3" Visibility="{Binding PanelLoading, Converter={StaticResource BoolToVis}}">
<controls:LoadingPanel x:Name="loadingPanel" VerticalAlignment="Stretch"
IsLoading="{Binding PanelLoading}"
Message="Calculating..."
SubMessage="Wait a minute"
/>
</Grid>
我们只想在需要时间的情况下显示加载器。当一些任务执行少于一些延迟时 - 就像闪烁一样。
当我需要显示指标时,我会尝试下一步:
public async Task StartSpinAsync(CancellationToken cancellationToken)
{
int delay;
if (!int.TryParse(ConfigurationManager.AppSettings["ApplicationDelay"], out delay))
{
delay = 0;
}
await Task.Delay(delay, cancellationToken);
await this.Dispatcher.InvokeAsync(() => IsLoading = true,
System.Windows.Threading.DispatcherPriority.Normal, cancellationToken);
}
public async Task StopSpinAsync()
{
await this.Dispatcher.InvokeAsync(() => IsLoading = false,
System.Windows.Threading.DispatcherPriority.Normal);
}
问题 - 当显示指示器时,它没有旋转,它被冻结。我认为这是因为UI线程被阻止了。
是否可以检查哪个块UI线程,是否可以从上面的代码中检查它?
答案 0 :(得分:0)
这是BusyLoaderAsync(Action doWorkAction)
的有问题的实施,因为它取决于doWorkAction
实施。
如果doWorkAction
同步如下:
BusyLoaderAsync(() =>
{
Debug.WriteLine(" == Action Start ");
Thread.Sleep(8000);
Debug.WriteLine(" == Action End ");
});
然后它锁定UI线程,并且在doWorkAction
结束之前UI中没有任何更新。结束后,tokenSource.Cancel();
取消忙指示符,并且永远不会更新。
如果doWorkAction
是异步的,请执行以下操作:
BusyLoaderAsync(async () =>
{
Debug.WriteLine(" == Action Start ");
await Task.Delay(8000);
Debug.WriteLine(" == Action End ");
});
然后doWorkAction
比StartSpinAsync
运行得更快,最终tokenSource.Cancel();
在开始之前取消忙碌指标,它也永远不会显示。
在同步的情况下,如果doWorkAction
可以在另一个帖子中运行,BusyLoaderAsync
可以如下
public async Task BusyLoaderAsync(Action doWorkAction)
{
using (var tokenSource = new CancellationTokenSource())
{
var tasks = new[] { Task.Run(doWorkAction), Task.Delay(1000) };
var result = Task.WaitAny(tasks);
if (result == 1)
{
loadingPanel.IsLoading = true;
await tasks[0];
loadingPanel.IsLoading = false;
}
}
}