HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Forced Async operation in a (event like) method

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
methodasynclikeoperationforcedevent

Problem

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 () => {
        if (!Directory.Exists(directory)) return;

        using (var context = _contextFactory.CreateContext()) {
            var existing = context.WatchDirectories.FirstOrDefault(wd => wd.Directory == directory);
            if (existing == null) {
                var childWatchers = context.WatchDirectories.Where(wd => 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 => AddDirectoryWatcher(directory));
            }
        }
    });
}


I just want to know if there is a better approach for this.

Solution

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 () => {
        if (!Directory.Exists(directory)) return;

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

            var childWatchers = context.WatchDirectories.Where(wd => 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.

Code Snippets

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

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

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

Context

StackExchange Code Review Q#79939, answer score: 2

Revisions (0)

No revisions yet.