12
\$\begingroup\$

I am working on creating some libraries for a project at work and I wanted to make sure I have this pattern correct. Assuming that the GetWidgets() method is what I am going to be exposing, which is the preferred method for this? Is there any fundamental difference between these two methods?

The first uses async/await and Task:

public async Task<List<Widget>> GetWidgets(DateTime date)
{
 using (var httpClient = new HttpClient())
 {
 var feed = "http://example.org/feed";
 var response = await httpClient.GetStringAsync(feed);
 var items = await SomeOtherAsyncMethod(response);
 return items.Where(item => item.StartDate.Date == date).ToList();
 }
}

The alternative uses Task.Factory.StartNew() and Result:

public Task<List<Widget>> GetWidgets(DateTime date)
{
 return Task.Factory.StartNew(() =>
 {
 using (var httpClient = new HttpClient())
 {
 var feed = "http://example.org/feed";
 var response = httpClient.GetStringAsync(feed).Result;
 var items = SomeOtherAsyncMethod(response).Result;
 return items.Where(item => item.StartDate.Date == date).ToList();
 }
 });
}

And if the second version is correct, should I be naming it GetWidgetsAsync()?

Reinderien
70.9k5 gold badges76 silver badges256 bronze badges
asked Oct 16, 2014 at 18:48
\$\endgroup\$

2 Answers 2

7
\$\begingroup\$

I'd prefer the first method because it's making more efficient use of resources (provided the async methods you call are really async and not just wrappers around synchronous methods) and it also looks cleaner.

To quote from this MSDN blog:

... the only asynchronous methods that should be exposed are those that have scalability benefits over their synchronous counterparts ...

What you are doing in your second method is basically calling the async methods in a synchronous way just to then in turn wrap it into a task. This will have scalability issues because it's using up a dedicated thread (at least in the current implementation of the task library) while the async methods you call might have more efficient means of achieving their asynchronicity (like IO completion ports or timer callbacks)

Glorfindel
1,1133 gold badges14 silver badges27 bronze badges
answered Oct 16, 2014 at 20:09
\$\endgroup\$
3
  • \$\begingroup\$ So there is where I think I am confused. Is var response = await httpClient.GetStringAsync(feed); var items = await SomeOtherAsyncMethod(response); not also a syncronous call? \$\endgroup\$ Commented Oct 16, 2014 at 20:38
  • \$\begingroup\$ @Schandlich: No. await will release the control back to the calling thread and the execution of the method will continue once the async call which is being awaited has finished. The execution will either resume on the original thread or another one depending on some options you can set. See MSDN for an in-depth explanation of how it all works. \$\endgroup\$ Commented Oct 16, 2014 at 21:40
  • \$\begingroup\$ Thank you very much. This also helped me a lot: msdn.microsoft.com/en-us/library/hh873177(v=vs.110).aspx \$\endgroup\$ Commented Oct 17, 2014 at 0:24
1
\$\begingroup\$
httpClient.GetStringAsync(feed).Result

You shouldn't do this. Result will synchronously block for the Task to complete, negating any benefits of using async. It can also easily lead to deadlocks.


should I be naming it GetWidgetsAsync?

Yes, both your versions should be named that way, to follow the Task-based Asynchronous Pattern.

answered Oct 18, 2014 at 15:41
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.