Forced Async operation in a (event like) method I have a piece of code that I am not feeling comfortable.


I don't want to block the UI
Read operation works synchronously (reading may broke 50 ms rule)
Save operation supports async (returns Task)
I have to await SaveChanges (so operation could be completed before Dispose)




public Task AddToMyProject(string directory) {
    return Task.Run(async () =&gt; {
        if (!Directory.Exists(directory)) return;

        using (var context = _contextFactory.CreateContext()) {
            var existing = context.WatchDirectories.FirstOrDefault(wd =&gt; wd.Directory == directory);
            if (existing == null) {
                var childWatchers = context.WatchDirectories.Where(wd =&gt; wd.Directory.StartsWith(directory));
                foreach (var watchDirectory in childWatchers) {
                    context.Delete(watchDirectory);
                    RemoveDirectoryWatcher(watchDirectory.Directory);
                }

                context.Insert(new WatchDirectory { Directory = directory });
                await context.SaveChanges()
                    .ContinueWith(t =&gt; AddDirectoryWatcher(directory));
            }
        }
    });
}


I just want to know if there is a better approach for this.
Instead of WatchDirectories.FirstOrDefault you can make use of Any() which is more meaningful.  

Also if you are checking Any() you can return early and save horizontal spacing.  

public Task AddDirectoryWatcher(string directory) {
    return Task.Run(async () =&gt; {
        if (!Directory.Exists(directory)) return;

        using (var context = _contextFactory.CreateContext()) {
            if (context.WatchDirectories.Any(wd =&gt; wd.Directory == directory)) { return; };

            var childWatchers = context.WatchDirectories.Where(wd =&gt; wd.Directory.StartsWith(directory));




This AddDirectoryWatcher() is using a context to delete and insert items. Doesn't the RemoveDirectoryWatcher() method already uses a context too ? If yes, the call to context.Delete(watchDirectory); is redundant.  



Instead of checking if the passed directory exists and silently returning , I would check this before calling the method and throw a DirectoryNotFoundException.