none
WPF UI thread problem RRS feed

  • Question

  •  This my code block.

    private async void BtnApplyall_Click(object sender, RoutedEventArgs e)
            {     
                try
                {
                    ucLoading.Visibility = Visibility.Visible;
                    await Task.Run(() => ApplyScenarios());
                }
                catch (Exception ex)
                {
                   throw;
                }          
            }

            public Task ApplyScenarios()
            {
                try
                {
                    Dispatcher.Invoke(() =>
                    {                    
                        ApplyAllScenarios(ucScenarioContainer.Children);
                        ucLoading.Visibility = Visibility.Hidden;
                    });             
                }
                catch (Exception ex)
                {
                   throw;
                }
                return Task.CompletedTask;
            }

    My problem is I clicked BtnApplyAll button and then my UI locked until process finished. And My progressbar not turn because of UI locked. I used Task and Dispacther but did not work. How can I handle this problem.

    Thursday, June 13, 2019 2:18 PM

All replies

  • Hi,
    your UI-Task is waiting:

    await Task.Run(() => ApplyScenarios());

    Run the task without wait!


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    Thursday, June 13, 2019 6:04 PM
  • I did but does not work. still UI locked.
    Friday, June 14, 2019 5:59 AM
  • Hi,
    your ApplyAllScenarios will be directed to the UI thread and block the UI thread. You must get the data from the UI elements (via dispatcher copy to thread saved members), then process this data in separate thread and at last populate the results in UI thread (via dispatcher).

    Try this demo. 

    XAML:

    <Window x:Class="WpfApp1.Window35"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1.Properties"
            mc:Ignorable="d"
            Title="Window35" Height="450" Width="800">
      <StackPanel>
        <Button Content="Start Upload" Name="BtnApplyall" Click="BtnApplyall_Click"/>
        <Label Content="Uploading in Progress" Name="ucLoading" Visibility="Hidden"/>
        <StackPanel Name="ucScenarioContainer"/>
      </StackPanel>
    </Window>

    CodeBehind:

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows;
    
    namespace WpfApp1
    {
      /// <summary>
      /// Interaction logic for Window35.xaml
      /// </summary>
      public partial class Window35 : Window
      {
        public Window35()
        {
          InitializeComponent();
        }
        private async void BtnApplyall_Click(object sender, RoutedEventArgs e)
        {
          try
          {
            ucLoading.Visibility = Visibility.Visible;
            await Task.Run(() => ApplyScenarios());
          }
          catch (Exception ex)
          {
            throw;
          }
        }
    
        public object ApplyScenarios()
        {
          try
          {
            // at first get data from UI (redirecting to UI thread)
            Dispatcher.Invoke(() =>
            {
              var res = ApplyAllScenarios(ucScenarioContainer.Children);
            });
            // simulate data processing in separate thread
            Thread.Sleep(1000);
            // at last change the properties of UI elements (redirecting to UI thread)
            Dispatcher.Invoke(() =>
            {
              ucLoading.Visibility = Visibility.Hidden;
            });
          }
          catch (Exception ex)
          {
            throw;
          }
          return null;
        }
    
        private object ApplyAllScenarios(object children)
        {
          return null;
        }
      }
    }
    


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    Friday, June 14, 2019 6:49 AM