wpfmultithreadinguser-interfaceasync-awaitfreeze

How to keep UI unblocked while processing in WPF C#


I've read many examples about threads and asynchronous..., but I can't make the UI in wpf c# not freeze when calculating files on a disk - I can't move the window..., I have to wait that the counting process ends. Once the counting is finished, control of the user interface is resumed.

My button code and the counting result in a texbox

    public static long DirSize(DirectoryInfo d)
{

    long size = 0;
    FileInfo[] fis = d.GetFiles();
    foreach (FileInfo fi in fis)
        try
        {
            {
                size += fi.Length;
            }
        }
        catch
        {

        }

   private async void Save_bkp_Click(object sender, RoutedEventArgs e)
  {

   await Task.Run(() =>
   {
       Dispatcher.Invoke(new Action(() => {

           TextBox_Dimensioni.Text = Convert.ToString((double)DirSize(new DirectoryInfo(CopiaFoto)));

       }));
   });

  }

If I don't put Dispatcher.Invoke I get the error: The calling thread cannot access this object because this object is owned by another thread. I've tried many ways but nothing always freezes...


Solution

  • Run the long running part inside of a task and await it. Then update the controls with the result.

    This will take care to return to the initial synchronization context (in this case: the UI thread).

    private async void Save_bkp_Click(object sender, RoutedEventArgs e)
    {
        var size = await Task.Run( () => DirSize( new DirectoryInfo(CopiaFoto) ) );
        TextBox_Dimensioni.Text = size.ToString();
    }