【问题标题】:BusyIndicator animation stops with delayed operationBusyIndi​​cator 动画因延迟操作而停止
【发布时间】:2021-02-28 18:43:32
【问题描述】:

我正在尝试显示从其他来源获取数据的繁忙指示器。

工作流程

  1. 忙指示符在进程启动时启动
  2. 正在获取数据。
  3. 停止忙碌指示器。

示例代码

Xaml

 <busyIndicator:BusyIndicator x:Name="BusyIndicator" IsBusy="False" >
        <Grid>
            <Button x:Name="showindicator" Height="100" Width="200" Content="ShowIndicator" Grid.Row="1" Click="Showindicator_Click"/>
        </Grid>
    </busyIndicator:BusyIndicator>

C#

private async void Showindicator_Click(object sender, RoutedEventArgs e)
        {
            BusyIndicator.IsBusy = true;
            await Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
            {
                // In my original code, fetching data here
                for (int i = 0; i < 5; i++)
                {
                    Console.WriteLine(i);
                    Thread.Sleep(1000);
                }
            }));
            BusyIndicator.IsBusy = false;
        }

在调度程序循环正在进行时忙碌指示器不会启动,指示器仅在循环后启动。在上述情况下,指示器未显示,但如果 IsBusy 标志未设置为 false,则指示器在循环后启动。

我不知道是我做错了什么还是逻辑不正确?请帮我解决这个问题。

【问题讨论】:

    标签: c# wpf xaml busyindicator


    【解决方案1】:

    您似乎在 GUI 线程上执行繁重的操作 - 这是因为 Dispatches.BeginInvoke 将操作分派给 GUI 线程。

    这可能更容易:

    BusyIndicator.IsBusy = true;
    await Task.Run(() =>
    {
        // this is now running in the background
    
        // In my original code, fetching data here
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine(i);
            Thread.Sleep(1000); 
    
            Dispatcher.BeginInvoke(() => 
            {  
                 // do UI stuff here
            });
        }
    });
    
    BusyIndicator.IsBusy = false;
    

    【讨论】:

    • 是的,上面的代码在繁忙指示器下工作正常,但在处理数据时我面临以下异常。 System.Windows.Markup.XamlParseException: '必须在与 DependencyObject 相同的线程上创建 DependencySource。'
    • @KarthikRajaAKR:那么您可能正试图从后台线程访问繁忙指示器或其他一些控件。这是不允许的。
    • 您可能正试图在“获取数据”代码中更改 GUI 上的某些内容。我已经更新了示例
    • @arconaut 感谢您的回复。在我的项目中,我使用线程函数获取的数据创建 UI。此处数据在我的项目中稍后用作 UI 的 DataContext。所以我不能在线程中进行与 UI 相关的更改。有什么我可以做的吗?
    • 您可以通过将它们放在发送到Dispatcher.BeginInvoke() 的操作中来进行与 UI 相关的更改。它可能看起来像这样:Dispatcher.BeginInvoke(() =&gt; UpdateUI(recentData)) 或在我上面的答案中看到类似的代码;)
    猜你喜欢
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 2013-08-03
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多