Very poor performance of IStorageQueryResultBase.ContentsChanged
I am trying to watch a large number of folders for changes using IStorageQueryResultBase.ContentsChanged. However, this is basically impossible due to performance issues. First of all, there is no option to make this fire only on 'rename' events (file creation, deletion or renaming), which is what I want, and it seems to fire multiple times even when there are no changes - for example opening a file open dialog from my app can cause it to fire. Also, it seems to watch for deep changes even though my query is shallow.
Now onto the main issue. Removing this handler seems to take an exponentially increasing amount of time depending on how many handlers there are to remove. I am doing all the removals using a single Task.Run. To remove 200 handlers takes 25 seconds, which is already ridiculously long. To remove 600 handlers takes 200 seconds. Adding 600 handlers only takes about 4 seconds. In addition, for al this time during adding and removal, if I try to open a file dialog from my app then it hangs. Also, Windows Explorer stops working properly.
Also, it appears that the runtime broker creates a new thread for every single ContentsChanged handler added. This means if I add 600, then I create 600 new threads. This seems very wasteful.
Ben Stevens commented
In addition, if I try to call GetItemsAsync on a query which doesn't have a ContentsChanged handler attached, then it doesn't pick up and changes since the query was first run. As a workaround, I have to do SetQueryOptions(query.GetQueryOptions) then call GetItemsAsync.