1

So I just want to make my service layer async.

I have a new service ProjectManagement and I want its GetProjects method to be asynchronous.

public Task<string> GetProjectsAsync()
{
    var json = JsonConvert.SerializeObject(_repository.All<Projects>());

    return json;
}

I know this method doesn't work, obviously because I'm return a string, not a Task<string>. So how do I use the Task.Run() to run this method and return the result?

I've looked at this documentation and I'm a bit confused on how to use it?

All I want to be able to do in my controller is:

var jsonData = await _projectManagement.GetProjectsAsync();
5
  • 2
    The only real reason do make the method asynchronous is if you can actually do the IO asynchronously. If you can't, you may as well just leave it as a synchronous method. Commented Jun 12, 2014 at 17:56
  • Returning a string when you have return type of method Task<string> is correct behavior. Just put async before your GetProjectsAsync() method. Commented Jun 12, 2014 at 17:57
  • 3
    @Abhijeet That's a terrible idea. That's creating a method that is synchronous and simply wrapping its result in a task, essentially making the statement that it's asynchronous a lie. You shouldn't do that. If you don't want to make the method asynchronous, you shouldn't lie to your callers and claim that you're asynchronous. Commented Jun 12, 2014 at 17:58
  • @Servy querying the database is an IO task... It can take a length of time to retrieve the data depending on what infrastructure lies around the web server. Commented Jun 12, 2014 at 19:20
  • @No1_Melman Yes, and so you want to do this asynchronously, rather than having a thread sitting around doing nothing while you wait for that IO operation to complete. If you have some method of inherently doing that IO asynchronously then you should be using it. If you don't, then there really isn't anything for you to do. You can't turn a synchronous method into one that does properly asynchronous IO; it's too late to change at that point. Commented Jun 12, 2014 at 19:24

2 Answers 2

5

When converting to async, you want to start at the "leaves" and work towards your controllers/UI. I've done a lot of conversions, and that's the best approach I've found.

So, first identify any operations that are naturally asynchronous; anything I/O-bound is a good bet. You've already identified one: the database calls.

Next, start at the lowest-level code, and make that asynchronous. This is where your problem is coming in; you're thinking about forcing asynchrony in the middle by using Task.Run, but you need to dive deeper to a lower level and make it asynchronous all the way.

For example, I'll assume that your repository is using Entity Framework and that your All<T> method looks something like this:

public List<T> All<T>()
{
  return _context.Set<T>().ToList();
}

Then you would start with making an asynchronous version of this repository method:

public Task<List<T>> AllAsync<T>()
{
  return _context.Set<T>().ToListAsync();
}

Once you have at least one asynchronous repository method in place, you can start to change your service layer to be asynchronous, so this code:

public string GetProjects()
{
  var json = JsonConvert.SerializeObject(_repository.All<Projects>());
  return json;
}

becomes this:

public async Task<string> GetProjectsAsync()
{
  var json = JsonConvert.SerializeObject(await _repository.AllAsync<Projects>());
  return json;
}

Once the service layer is asynchronous, then you can change your controllers to be asynchronous.

Sign up to request clarification or add additional context in comments.

5 Comments

I cant implement the AllAsync method because it says "cannot implicitly convert List to Task"
Take another look at the code. It's ToListAsync, not ToList.
Acidentally tried to cast to a completely different type, List to IQueryable :P
I know this is old now, I've actually come along way since then.. My short question is will that pull JsonConvert up into the await state machine?
@CallumLinington: I'm not entirely sure what you mean. The call to the JsonConvert.SerializeObject will be in the state machine, yes.
-3

you should try this link http://www.dotnetperls.com/async

private async void DoAsyncWork()
{ 
   var data = await GetProjectAsync();
}

async Task<string> GetProjectAsynce()
{
    // code to get stuff done
    // await key word may be needed depending on
    // what you are doinf
    return JsonConvert.SerializeObject(myRepository.All<Projects>());
    // convert to string first of course 
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.