0

I am trying to accomplish following tasks with KnownFolders, i.e: VideoLibrary in my UWP app

  1. Faster Load Time. ( I need to load thumbnails and file names from the KnownFolders, which might take little more time if the library has huge number of files. Is there a faster way to cache and store them , maybe in sqlite database, and on each next run just get them from DB, can that be faster?

  2. Syncing with the system file changes ( if a new file is added or deleted within that specific library, while the app is running, how can the app be notified about that )

  3. Basically I want the app to load the library data faster as it opens so what would be the recommended way to achieve that? Should I use a background task for the app? but keeping data in memory when app isnt running might not be a good solution or is it? or maybe I can start the process of extracting data within App.xaml.cs as soon as the app launches ( before navigating to library page ) would that make performance improvement?

  4. Basically : I am looking for some suggestions and discussion here because there not might be a strict answer for my question here. Thanks in advance any suggestion will be appreciated. MY main 2 goals are to sync the library with delete and add files in the physical folder, and improve loading performance of library in the app. ( and yeah I am loading the library in a gridview with thumbnails as well.

Muhammad Touseef
  • 4,357
  • 4
  • 31
  • 75
  • This is an article on using [search indexer](https://msdn.microsoft.com/en-us/magazine/mt620012.aspx?f=255&MSPPError=-2147217396). Indexing is what the OS provides to speed up the enumeration of large amount of files. Search for the example "Optimized Code for Enumerating a Library" in the article to get started. – kennyzx Jun 17 '17 at 12:27
  • that is brilliant, thanks a lot @kennyzx – Muhammad Touseef Jun 17 '17 at 12:39

1 Answers1

1
StorageFileQueryResult fileQuery;

async void CreateWatchFolder(StorageFolder folder)
    {
        var options = new QueryOptions();
        options.FolderDepth = FolderDepth.Deep;
        fileQuery = folder.CreateFileQueryWithOptions(options);
        _fileQuery.ContentsChanged += OnContentsChanged;
        var files = await _fileQuery.GetFilesAsync();
    }

    async void OnContentsChanged(IStorageQueryResultBase sender, object args)
    {
        // Do stuff, e.g. check for changes
    }

For #2 of your question, this will give you a watch folder. Any time there is a change in that StorageFolder it will fire the event. It doesn't know which file changes were made, but you can write code to check each time. See here for more details.

Regarding #1, it's really hard to say it's worth testing out. I personally have had terrible performance when playing around with Sqlite and EF with UWP, but I'm anything but an expert on that.

Question #3, you might consider caching your thumbnails to one of the app-data folders. LocalCache would be the obvious choice, but actually if you do just Local then you can bind URI paths for the image sources in your UI. This doesn't work with images in LocalCache last I checked (about March or so) but it does with Local. It's much faster than loading the file as a StorageFile and then creating a Bitmap with it.

Sean O'Neil
  • 1,222
  • 12
  • 22
  • Also note the last line of the first method. Doing a GetFilesAsync() is required to start the folder watching. – Sean O'Neil Jun 17 '17 at 11:40
  • so when should I execute this method you provided? I mean I can just execute it when the app starts, and until the app is closed, it will keep watching the folder ( KnownFolders.VideoLibrary ) and if its content is changed in any way from outside the app, this event will fire up right? – Muhammad Touseef Jun 17 '17 at 12:15
  • what is difference between local and localcache? are you talking about application local folder? can u please provide a little insight on how theycan be cached? I mean will they be saved as .png files in local folder? if yes then .png files will also be retrieved as SorageFiles later on right? is that faster? Also please suggest me about other properties like, file names, should I save them in db? or retrieve them everytime from Library, wht would be a better option? Thanks – Muhammad Touseef Jun 17 '17 at 12:22
  • @SeanO'Neil your filequery object will go out of scope in the code you posted and the event will never fire. it should be a local field in the class. – MrCSharp Jun 17 '17 at 12:25
  • or it can be global, so it can be used throughout the app? @Rafael – Muhammad Touseef Jun 17 '17 at 12:27
  • @touseef of course it can be global. it really depends on your requirements and how your project is structured. just make sure the object doesn't go out of scope, otherwise the GC will dispose it. – MrCSharp Jun 17 '17 at 13:20
  • @Rafael haha yeah you mentioned that before. https://stackoverflow.com/questions/43734831/cant-create-reliable-watch-folder-in-uwp-app – Sean O'Neil Jun 17 '17 at 16:10
  • @SeanO'Neil looks like it is my specialty now ;) – MrCSharp Jun 17 '17 at 16:11
  • @touseef Yes, you can cache your images to your app's Local or LocalCache folder. You can have a startup method to do this in App.xaml.cs or called from the constructor of your base view model. Presumably this would mean a long time to launch the app the first time but subsequent launches would be fast if the cache files are there. – Sean O'Neil Jun 17 '17 at 16:18
  • @touseef A file almost anywhere on the file system, even if it's in a KnownFolder, needs to be loaded as a StorageFile object and converted to a stream then a BitmapImage in order to display it on your UI. This does not happen instantaneously and a bunch of them does cause a delay. However, I said almost anywhere. If your images are in your Assets folder, or in your Local folder, you can bind your UI element to a URI instead of a BitmapImage object. A URI is just a path to the image file. It doesn't waste time checking if it's there until it needs to actually display it. – Sean O'Neil Jun 17 '17 at 16:25
  • So like means the ViewModel property has to see if the image is there and loads it into memory. If the file isn't there it will throw an exception. But if you do – Sean O'Neil Jun 17 '17 at 16:39
  • thts great, but what if our local folder reaches its storage capacity, I mean isnt there a limit in that folder? Also lets suppose I store and load images faster, but I will still need to load StorageFiles for file name and other properties right? wouldnt that take longer time as well? so should I cache those properties in a db as well? what are your suggestions about that? – Muhammad Touseef Jun 18 '17 at 20:52
  • I don't know of any arbitrary capacity limit imposed. Yes you can store image metadata in a db or in a file. I don't know enough about your project or your specs to tell you the best way to do anything. These are things you would need to experiment with. – Sean O'Neil Jun 19 '17 at 09:31
  • thankyou so much for all the help and tips ;) @SeanO'Neil – Muhammad Touseef Jun 19 '17 at 12:08