Skip to content

Conversation

aftab23822
Copy link

@aftab23822 aftab23822 commented Sep 18, 2025

Report: File Size Calculation Freezing Issue

1. Problem Overview

Our WPF application was becoming unresponsive ("Not Responding" state) when performing file size calculations on large directories.

  • Example: scanning folders with 50,000+ files caused the UI to freeze for several seconds or indefinitely.
  • This created a poor user experience, as the app appeared frozen and Windows would show it as not responding.

Closes #14306


2. Investigation

We used Visual Studio Performance Profiler (CPU Usage tool) to understand where the app was spending time.

Findings:

  • Almost all CPU time was spent in file size calculation routines.
  • The entire computation was happening in a single, long-running synchronous task, blocking the UI thread.
  • Because WPF apps rely on the UI thread to redraw and respond to input, the UI became unresponsive during this work.

3. Root Cause

  • File size computation was being performed in a tight loop across thousands of files.
  • No opportunity for the UI thread to "breathe" (yield execution).
  • As a result, even though the calculation eventually completed, the user perceived the app as frozen.

4. Solution

We redesigned the FileSizeCalculator to:

  1. Introduce async/await – run expensive work without blocking the UI thread.
  2. Batch processing (chunking) – process files in groups (e.g., 1000 at a time). After each batch, yield control back to the system so the UI remains responsive.
  3. Efficient file access via Win32 API (CreateFile, GetFileSizeEx) – avoids unnecessary overhead of FileInfo for each file.
  4. ConcurrentDictionary caching – prevents recalculating file sizes repeatedly.
  5. Cancellation support – users can cancel ongoing operations.

Example snippet (batch logic):

if (batch.Count >= ChunkSize)
{
    ComputeFileSizeBatch(batch);
    batch.Clear();
    await Task.Yield(); // let UI update
}

FileSizeCalculator Report.docx


5. Results

  • Tested with 50,000+ files.
  • The calculation now completes successfully without UI freezing.
  • Application remains responsive (user can move/resize window, cancel operation, see progress).
  • Performance improved due to batching and efficient native calls.

6. Key Takeaways

  • Long-running operations in WPF must not block the UI thread.
  • Chunking and async/await is a reliable pattern for large data processing.
  • Profiling tools (like Visual Studio CPU Usage) are essential for identifying hotspots.

@yaira2 yaira2 self-requested a review September 18, 2025 20:29
@yaira2 yaira2 changed the title Main #14306 Feature: Improved performance when calculated folder sizes Sep 18, 2025
@Josh65-2201
Copy link
Member

Based on C:\Windows\WinSxS after the folder loaded and was just the folder calculations, for 4.0.11 it was about 8% CPU usage and 58 seconds, this PR was about 8% CPU usage but 1 minute slower to show total folder size on the status bar.

C: and C:\Windows\System32 where similar CPU and time on 4.0.11 and this PR

@yaira2 yaira2 changed the title Feature: Improved performance when calculated folder sizes Feature: Improved performance when compressing files Sep 19, 2025
@yaira2 yaira2 requested a review from Copilot September 19, 2025 02:47
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR improves the performance and responsiveness of file size calculations in the WPF application by replacing a blocking synchronous approach with an asynchronous batch processing system. The changes address UI freezing issues when processing large directories (50,000+ files).

  • Replaced Win32 FindFirstFileEx/FindNextFile API calls with managed Directory.Enumerate methods
  • Implemented batched processing with Task.Yield() to maintain UI responsiveness
  • Introduced a new ComputeFileSizeBatch method for efficient batch file size computation

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@aftab23822
Copy link
Author

Looking forward to implementing CoPilot Ai's suggestions in the PR. Also looking to improve performance as per @Josh65-2201's suggestion.

@aftab23822
Copy link
Author

Based on C:\Windows\WinSxS after the folder loaded and was just the folder calculations, for 4.0.11 it was about 8% CPU usage and 58 seconds, this PR was about 8% CPU usage but 1 minute slower to show total folder size on the status bar.

C: and C:\Windows\System32 where similar CPU and time on 4.0.11 and this PR

Hi @Josh65-2201,
I’ve verified that the method FileSizeCalculator.ComputeSizeAsync is not used when checking file/folder details.
It’s only invoked during operations like copy, move, delete, or archive.

Thanks.

1) Adaptive chunking → starts at 500, doubles gradually to 5000 for speed on large dirs.

2) Parallel batch processing in ProcessBatchAsync using Parallel.ForEach.

3) _computedFiles check before adding to batch → avoids double-counting.

4) CancellationToken support inside parallel loops.

5) UI responsiveness with await Task.Yield() after each batch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bug: Crash when navigating and creating an archive at the same time
3 participants