question

marck0zz-3254 avatar image
0 Votes"
marck0zz-3254 asked marck0zz-3254 commented

UWP Unity app Bad Performance

Hello all.

I have this Unity app that I'm developing for Windows standalone and UWP(Win10). Both works fine but in the UWP one, the more you use the app, the worst the performance goes.

In the app the user can import (from local disk) an image or folder with images to loade them in a 3D model. This works as it should be, BUT, every time I copy a new folder to the ".ApplicationData.Current.LocalFolder" the use of the CPU increse a lot. Have a look on the image of my Task Manager (the highlited one), after every "import" process. For the Win Standalone this doesn't happens.

86528-taskmanageruwp.png

Since the only different between both builds is basically the import folder process (copy to local folder) -Windows APIs (like Windows.Storage) vs System.IO- my guess is that my code is causing this intense use of CPU (I'm new on async/await/Task system).

Is this code that CPU intensive? And why it doesn't decrese after every import process?


 //******************Check folder size******************
 async Task CheckFolderSize(Windows.Storage.StorageFolder thisFolder, CancellationToken token_)
 {
     if (token_.IsCancellationRequested)
         return;
    
     if (timer.Elapsed.TotalSeconds > 60)
     {
         if(modelFault == "error_007")
             return;
         else
         {
             modelFault = "error_007";
             Debug.LogError("Assing er007");
             return;
         }
     }
    
     Debug.LogError("Task has started");
    
     List<Task> tasks = new List<Task>();
    
     await FileSize(thisFolder, token_);
    
     Debug.LogError("Get files size done.");
    
     foreach (var folders in await thisFolder.GetFoldersAsync())
     {
         if (timer.Elapsed.TotalSeconds > 60)
         {
             if (modelFault == "error_007")
                 break;
             else
             {
                 modelFault = "error_007";
                 Debug.LogError("Assing er007");
                 break;
             }
         }
         else
         {
             tasks.Add(CheckFolderSize(folders, token_));
             Debug.LogError("One folder found at " + folders.Path);
         }
    
         if (token_.IsCancellationRequested)
             return;
     }
    
     await Task.WhenAll(tasks);
    
     timeElapsed += timer.Elapsed.TotalSeconds;
    
     Debug.LogError("Task has DONE in: " + timer.Elapsed.TotalSeconds + "seg");
 }
    
 async Task FileSize(Windows.Storage.StorageFolder inFolder, CancellationToken token_)
 {
     Debug.LogError("Time elapsed : " + timer.Elapsed.TotalSeconds + "seg");
     if (token_.IsCancellationRequested)
         return;
    
     if (timer.Elapsed.TotalSeconds > 60)
     {
         if (modelFault == "error_007")
             return;
         else
         {
             modelFault = "error_007";
             Debug.LogError("Assing er007");
             return;
         }
     }
     else
     {
         var fileSizeTasks = (await inFolder.GetFilesAsync()).Select(async file => (await file.GetBasicPropertiesAsync()).Size);
                            
         var sizes = await Task.WhenAll(fileSizeTasks);
         var thisSize = sizes.Sum(l => (long)l);
         folderSize += thisSize;
    
         Debug.LogError("One Task Done");
     }
 }
    
    
 //******************Copy from local disck to LocalFolder******************
 async Task CopyFolder(Windows.Storage.StorageFolder folderToCopy, Windows.Storage.StorageFolder targetFolder, CancellationToken token1)
 {
     if (token1.IsCancellationRequested)
         return;
    
     if (modelsCount > 1)
     {
         if (modelFault == "error_004")
             return;
         else
         {
             modelFault = "error_004";
             Debug.LogError("Assing er004");
             return;
         }
     }
    
     //if (!await FolderExistAsync(folderToCopy.Name, targetFolder))
     //    await targetFolder.CreateFolderAsync(folderToCopy.Name, Windows.Storage.CreationCollisionOption.ReplaceExisting);
    
     if (!FolderExist(targetFolder.Path, folderToCopy.Name))
     await targetFolder.CreateFolderAsync(folderToCopy.Name, Windows.Storage.CreationCollisionOption.ReplaceExisting);
    
     Windows.Storage.StorageFolder destination = await targetFolder.GetFolderAsync(folderToCopy.Name);
    
     Debug.LogError("folder created: " + destination.Path);
    
     foreach (var file in await folderToCopy.GetFilesAsync())
     {
         if (token1.IsCancellationRequested)
             return;
    
         if (modelsCount > 1)
         {
             if (modelFault == "error_004")
                 return;
             else
             {
                 modelFault = "error_004";
                 Debug.LogError("Assing er004");
                 return;
             }
         }
    
         string ext = Path.GetExtension(file.Name);
    
         HashSet<string> set = new HashSet<string>() { ".gltf", ".glb", ".bin", ".png", ".jpg", ".jpeg", ".bmp" };
         if (set.Contains(ext))
         {
             if (ext == ".gltf" || ext == ".glb")
             {
                 modelsCount++;
                 Debug.LogError("gltf count + 1");
    
                 if (modelsCount > 1)
                 {
                     modelFault = "error_004";
                     Debug.LogError("model = error04");
                     break;
                 }
                 else
                 {
                     path_ = Path.Combine(destination.Path, file.Name);
                     string writePath = path_;
    
                     writePathObj = writePath;
                     importedName = Path.GetFileNameWithoutExtension(file.Name);
    
                     Debug.LogError("GLTF File: " + writePathObj);
                 }
             }
             await file.CopyAsync(destination, file.Name, Windows.Storage.NameCollisionOption.ReplaceExisting);
         }
         else
         {
             Debug.LogError("Trash File: " + file.Path);
         }
     }
    
     foreach (var newFolder in await folderToCopy.GetFoldersAsync())
     {
         if (token1.IsCancellationRequested)
             break;
    
         if (modelsCount > 1)
         {
             if (modelFault == "error_004")
                 break;
             else
             {
                 modelFault = "error_004";
                 Debug.LogError("Assing er004");
                 break;
             }
         }
         await CopyFolder(newFolder, destination, token1);
     }
 }
    
 bool FolderExist(string destination, string foldername)
 {
     string FolderPath_ = Path.Combine(destination, foldername);//Get the full path to the new model folder
     if (Directory.Exists(FolderPath_))
         return true;
     else
         return false;
 }


I'll thank any help or advice.





windows-10-generalwindows-uwpwindows-10-hardware-performance
taskmanageruwp.png (23.8 KiB)
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

By making use of the UWP Task monitor (UWPTaskMonitor) the results doesn't show any background task or aditional process that could be using that amount of CPU.


0 Votes 0 ·

1 Answer

AryaDing-MSFT avatar image
0 Votes"
AryaDing-MSFT answered marck0zz-3254 commented

Hi,

Welcome to Microsoft Q&A!

There are much code about getting the file size, which will also affect the memory. Could you please try to optimize the copy process? I suggest you could customize a method to copy all files and subfolders in the folder to ApplicationData.Current.LocalFolder like the following.

Note that declare the broadFileSystemAccess capability in package.appxmainfest.

 private async void Button_Click(object sender, RoutedEventArgs e)
         {
              
             StorageFolder assetsFolder = await StorageFolder.GetFolderFromPathAsync(@"D:\Test Folder");
              
            var folder= ApplicationData.Current.LocalFolder;
    
            await CopyFolderAsync(assetsFolder, ApplicationData.Current.LocalFolder,null);
         }
    
         public static async Task CopyFolderAsync(StorageFolder source, StorageFolder destinationContainer, string desiredName = null)
         {
             StorageFolder destinationFolder = null;
             destinationFolder = await destinationContainer.CreateFolderAsync(
                 desiredName ?? source.Name, CreationCollisionOption.ReplaceExisting);
    
             foreach (var file in await source.GetFilesAsync())
             {
                 await file.CopyAsync(destinationFolder, file.Name, NameCollisionOption.ReplaceExisting);
             }
             foreach (var folder in await source.GetFoldersAsync())
             {
                 await CopyFolderAsync(folder, destinationFolder);
             }
         }



If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you for the answer!!

I simplified the code as you suggested and by do so, I notice that the problem was in another part of the code, I'm starting two task to "monitor" the behaivior in the methods above 1 for checking the time it takes get the folder/file size, and another to check the number of file in the folders, if time > 45 sec I cancel the "CheckFolderSize" and if the number of files > 10 I cancel the "CopyFolder" task but never cancel those monitors tasks once the jobs has done, so they are running all the time. So, I added a code to cancel those task like this: task-cancellation

And that solved the problem.


0 Votes 0 ·