【发布时间】:2016-01-11 17:05:51
【问题描述】:
在 MainWindow 中,我有 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>
控制加载面板有 2 个额外的方法:
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);
}
我们希望仅在确实需要时间时才显示加载器。因为当某些任务执行的时间少于某个延迟时 - 就像眨眼一样。
当我需要显示指标时,我会尝试下一步:
_mainWindow.BusyLoaderAsync(() => _resultViewModel.InitChart(lineChart, generalChart)).ConfigureAwait(false); // code which initialize WPF toolkit chart as example
问题 - 显示指示器时,它不旋转,它被冻结。我认为是因为 UI 线程被阻塞了。
是否可以检查阻塞 UI 线程,是否可以从上面的代码中检查它?
【问题讨论】:
-
一个非常简单的检查,执行你的应用程序,等待你的加载器出现并且不旋转,暂停执行并检查线程面板,看看你的代码在哪里暂停,第一个线程应该是 UI线程。
-
@Gusman,是的,第一个线程是主线程,据我所知,在 WPF 中是 UI 线程
-
这不是一个问题,我的意思是,如果你转到那个线程和调用堆栈,你会看到是什么阻塞了 UI 线程...
-
@Gusman,好吧,那么我无法检测到什么方法阻止 UI...在 CallStack 中我只能看到这个 i.imgur.com/BmrE9gL.png 而没有我的方法
-
好像有什么东西阻止了控件的创建
标签: c# wpf multithreading