简体   繁体   English

UI线程被阻止

[英]UI thread is blocked

In MainWindow I have async method which displays busy Indicator 在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);
        }
    }

Loading Panel looks like : 加载面板看起来像:

<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>

Control Loading Panel has 2 additional methods : 控制加载面板还有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);
    }

We want to show loader only if it realy takes time. 我们只想显示加载程序,除非确实需要时间。 Cause when some task executes less than some delay - it is like blink. 当某些任务执行的时间少于延迟时的原因-就像眨眼一样。

When I need to show indicator I try next : 当我需要显示指标时,我尝试下一个:

_mainWindow.BusyLoaderAsync(() => _resultViewModel.InitChart(lineChart, generalChart)).ConfigureAwait(false); // code which initialize WPF toolkit chart as example

Problem - when indicator is shown, it doesn't spining, it is freezed. 问题-显示指示器时,它没有旋转,而是冻结了。 I think it is because UI thread is blocked. 我认为这是因为UI线程被阻止了。

Is it possible to check what block UI thread and is it possible to check it from code above? 是否可以检查哪个块UI线程,并且可以从上面的代码中对其进行检查?

It is problematic implementation of BusyLoaderAsync(Action doWorkAction) because it depends on doWorkAction implementation. 这是BusyLoaderAsync(Action doWorkAction)有问题的实现,因为它依赖于doWorkAction实现。 If doWorkAction is synchronous like: 如果doWorkAction是同步的,例如:

BusyLoaderAsync(() =>
{
    Debug.WriteLine(" == Action Start ");
    Thread.Sleep(8000);
    Debug.WriteLine(" == Action End ");
});

then it locks UI thread, and nothing updates in UI until doWorkAction ends. 然后它将锁定UI线程,直到doWorkAction结束之前,UI中都不会更新。 After it ends, tokenSource.Cancel(); 结束后, tokenSource.Cancel(); cancels the busy indicator, and it can never updates. 取消忙碌指示器,它永远不会更新。

If doWorkAction is asynchronous like: 如果doWorkAction是异步的,例如:

BusyLoaderAsync(async () =>
{
    Debug.WriteLine(" == Action Start ");
    await Task.Delay(8000);
    Debug.WriteLine(" == Action End ");
});

then doWorkAction runs faster then StartSpinAsync and eventually tokenSource.Cancel(); 然后doWorkAction运行速度更快,然后StartSpinAsync并最终tokenSource.Cancel(); cancels the busy indicator before it starts, and it also never indicates. 在开始之前取消忙碌指示器,并且也从不指示。

In synchronous case, if doWorkAction can run in another thread, BusyLoaderAsync can be as following 在同步情况下,如果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;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM