Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to rewrite my Utils library with Async/Await

I have a lot of Utils classes that I use for many different projects, most of them are static and made out of static methods that usually don't even call each others.

My intention is to take advantages from the new async/await features but without rewriting everything, so my question is: can I just add a new method for each existing method named MethodAsync with the Task.Run(() => MethodName)?

example:

//old code that will not be removed
static void DoSomething()
{ ... }

//new code that will be added
static async Task DoSomethingAsync()
{
   //not really sure if Im supposed to use await/async here.
   //isn't Task awaitable even without async??
   return await Task.Run(() => DoSomething());
}

Basically in the old code I just had a normal sync method while in the new one I have an async method that could even run in another thread if the CLR see it as a CPU-bound method.

If I correctly understand, every asyncronous method contains by definition an await to an awaitable object which is a Task or another asyncronous method.

that means that whenever I can use an async .NET method, I should await it and mark my caller method as async.

But, every other method that do not call any async method but could take some time to complete should be called with a Task.Run call.

right?

EDIT

so I have read all the posted links, the best practices on msdn and a few blog posts but I still need a complete routine to follow when coding with the new async/await feature. this is what I get so far:

1) every .NET method that has an async alternative should use the async alternative. (As far as I know the .NET async methods already exists ONLY for methods that can be async).

2) every method that use async methods should be made async too.

3) every method that do not use async methods (cause there aren't available) but still takes some cpu-time to execute should be made async by wrapping them using Task.Run (I understand that in this case it should be the client to use Task.Run if they want but since im only adding these wrappers for methods that takes more than 50ms to execute and there will be still available the non-async version of the method, I still don't see why I shouldn't place this wrapper in the library).

4) every method that takes non-cpu-time cause it's waiting for other sources (like internet, database, events, etc...) should use TaskFactory.FromAsync or TaskCompletionSource.

5) System.Threading.Tasks.Parallel.Invoke(method1, method2, etc...) is now deprecated. From what I read Task.Run already run concurrent threads if the CLR thinks that concurrency is required. So it seems that Task.Run already uses Parallel.Invoke when needed.

like image 720
Simone Avatar asked Dec 19 '22 20:12

Simone


1 Answers

I was finally able to find good resources that cleared all my doubts:

the first one is "The Task-based Asynchronous Pattern" available at http://www.microsoft.com/en-us/download/details.aspx?id=19957 This document explains the async/await feature, how/when to use it, it contains many practical examples and a few of very usefull static methods that im now using on every project!

The second one is "The zen of async: Best practices for best performance" available at http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-829T which is a complete overview of the async feature, with some coverage of the Parallel features and it also explains why it should never be the library that use Task.Run() method but it should be a consumer choice instead.

So in the end I was really confusing multithreading with asynchronous code and I couldn't grasp the advantages of async code because I was just looking at 1 single method at the time while the real benefits of async code can only be seen if the entire project (or at least a consistent portion of it) is written following the async pattern. For example in asp.net, if there isn't any blocking code (everything written in a async fashion way), then a thread can serve another client while yours is awaiting an async operation, improving scalability, while in a xaml application a thread that launch an async operation can immediately go back to supporting your UI instead of just waiting that operation to be over, improving responsiveness.

like image 126
Simone Avatar answered Dec 22 '22 09:12

Simone