2

I'm wondering if it is correct to do some async operation in the following way.

Here is the sync classic code to get some data with a Find method:

public override Personne Find(object id)
    {
        return this.dbSet.OfType<Personne>()
                                .Include(a => a.Adresse)
                                .Include(c => c.PersonneCivilite)
                                .SingleOrDefault<MajeurProtege>(p => p.PersonneId == (int)id);
    }

Well, no issue with that as it is classic.

Now to have the same method Async i can write it like this :

    public async override Task<Personne > FindAsync(object id)
    {
        return await this.dbSet.OfType<Personne >()
                                .Include(a => a.Adresse)
                                .Include(c => c.PersonneCivilite)
                                .SingleOrDefaultAsync<MajeurProtege>(p => p.PersonneId == (int)id);
    }

But is the following method do strictly the same thing ? As it could allow me to write my async method without code pasting my queries parameters.

 public async override Task<Personne> FindAsync(object id)
    {
        return await Task.Run<Personne>(() => Find(id));
    }
Predalpha
  • 139
  • 1
  • 9
  • What is the point of this question? Just use the async methods, you can also use `FindAsync` – DavidG Feb 10 '17 at 00:18
  • return Task.Run(() => Find(id)).wait() – Mohamad Mahmoud Darwish Feb 10 '17 at 00:20
  • 2
    @MikeDarwish then it will not be async – CodingYoshi Feb 10 '17 at 00:21
  • The question is about my async code (2nd block). Does it work the same as if i were calling SingleOrDefaultAsync ? – Predalpha Feb 10 '17 at 00:22
  • looks that your question is answered here: http://stackoverflow.com/questions/21817569/use-of-include-with-async-await, and yes you are correct that replacing `SingleOrDefault` with `SingleOrDefaultAsync` does the trick. – Mobigital Feb 10 '17 at 00:24
  • @Mobigital Previously i was doing that that way : public async override Task FindAsync(object id) { return await this.dbSet.OfType() .Include(a => a.Adresse) .Include(c => c.PersonneCivilite) .SingleOrDefaultAsync(p => p.PersonneId == (int)id); } – Predalpha Feb 10 '17 at 00:27
  • the question is - what benefit do you expect from doing this? The real gains of async come when the calls you async wait on release their threads and are waiting on io completion. All others are just complicated ways of doing things in parallel, ie 'do a while waiting for b to finish' and there are simpler ways to do that – pm100 Feb 10 '17 at 00:27
  • @Predalpha, actually now I don't think I understand your question. Can you re-write it. There is a mixed wording in the paragraph between the 1st and 2nd code blocks. – Mobigital Feb 10 '17 at 00:28
  • @pm100 : just asking. if my result is very heavy, i dont want to freeze the UI. Ans was wondering if that code could be equivalent to SingleOrDefaultAsync – Predalpha Feb 10 '17 at 00:29
  • @Mobigital : ok i rewrite trying to be less confusing – Predalpha Feb 10 '17 at 00:31
  • if you look at .net's async code through jetbrains debugger you will see tons of these `await Task.Run()` wrapping around non-async methods as a substitute for real Async. So you're probably fine. – Mobigital Feb 10 '17 at 00:31
  • Just a side note, neither of your async examples would need to use the `async`/`await` modifiers, but should just return the `Task`s themselves. This is because the compiler adds a state machine into the code when compiled for every `async`/`await` used which adds overheads. You therefore should defer use of `async`/`await` until you actually need to deal with the result of `Task`. – Adrian Sanguineti Feb 10 '17 at 00:45
  • @Mobigital thank you. it seems to work but the Jason Lind answer makes me doubt about what im trying. Maybe i d rather use the classic way. – Predalpha Feb 10 '17 at 00:49
  • @Adrian You re totally right. Apologies for this, i forgot to remove async await keywords of those methods for the post ive previously edited. – Predalpha Feb 10 '17 at 01:00

1 Answers1

3

The code you posted does not operate the same as SingleOrDefaultAsync, in fact it would likely perform worse than if you didn't do a Task.Run/async at all as Task.Run has overhead.

SingleOrDefaultAsync is a true async call to the database, in fact if you use CancellationToken and cancel the query it will actually kill the query in your database.

Jason Lind
  • 263
  • 1
  • 2
  • 15