create asynchronous and synchronous methods for a repository - c#

I have a repository with a method Insert that returns an int (the methods and types are not relevant here). I am thinking to create synchronous and asynchronous insert methods for this repository. For the asynchronous method is it a good practice to enclose the synchronous Insert method in a task to avoid the code duplication?

No, this is not a good practice, as detailed by Microsoft's Stephen Toub here:
https://blogs.msdn.microsoft.com/pfxteam/2012/03/24/should-i-expose-asynchronous-wrappers-for-synchronous-methods/
... and by Stephen Cleary here:
http://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-dont-use.html
Long story short, if all your method does is wrap a synchronous call in Task.Run, that's trivial and I'm sure the caller is perfectly capable of doing it themselves. There is no need to increase the surface area of your API unless you have a naturally asynchronous operation (or unless you know that in the future you'll be able to provide one, and therefore want the consumers to target the XxxAsync method from day one).
As a bonus, here's a real life example of async wrapper methods being removed from a popular library:
JSON.NET used to provide SerializeAsync and DeserializeAsync methods which were just wrappers around their synchronous counterparts using Task.Factory.StartNew. Those were eventually obsoleted as they don't add value to the API and were deemed a potential scalability issue. The full discussion which led to this change can be found here:
https://github.com/JamesNK/Newtonsoft.Json/issues/66

Related

Using Task.Run for synchronous method in service

I've read a lot of articles about asynchronnous programming, but I'm not sure in one thing. I have 3rd party winrt library, written in C++ and I want to wrapp it. So now I have:
public Task LoginAsync(){
return Task.Run(winrtLibrary.Login();)
}
According Stephen Cleary and Stephen Toub blogs, it is not good solution. But when I use the method synchronously, my UI will not be responsive and will be blocked.
Is it better to expose service method synchronously and in UI use Task.Run?
What Stephen Toub means by
do not use Task.Run in the implementation of the method; instead, use Task.Run to call the method
Is that you shouldn't use Task.Run to hide CPU bound work behind async methods (Task returning methods). If you need to wrap external code, hide it behind an interface which reflects what this code do. Any asynchronous I/O can (and should) be exposed as Task returning methods, and CPU bound work must be exposed with the proper API. Let the consumers of your code to decide for themselves how to use that code. When you happen to by the consumer too, use Task.Run to run your synchronous code (now wrapped and exposed via interface) where it is very clear that you are offloading CPU bound work. In UI apps, for example, you should call Task.Run in your UI layer (and not deep down in your BL or even DA layers), where it is very clear that the UI offloads some CPU bound work.
Why do you think, that I shouldn't call Task.Run in BL? What if I have
ViewModel, which references BL and BL references service layer (in my
case is it wrapper).
I think that a method signature should reflect exactly what the method does.
The best I can do is to redirect you back to Cleary's article:
When a developer sees two methods in an API winrtLibrary.Login() and winrtLibrary.LoginAsync(), the convention is that they represent a naturally-asynchronous
operation. In other words, the developer expects that winrtLibrary.LoginAsync() is
the “natural” implementation and that winrtLibrary.Login() is essentially a
synchronous (blocking) equivalent of that operation. That API implies
that winrtLibrary.Login will at some point have the calling thread enter a wait
state as it blocks for the naturally-asynchronous operation to
complete.
You can still hide synchronous code behind async method and follow Cleary's rule of thumb, if you sign your method as public Task OffloadLoginToTheThreadPool(). But I think (and apparently Cleary, too) that the alternative of simply calling Task.Run from the UI (or Controller) is a much better approach, and it follows the principles of Clean Code.

Pitfalls of wrapping callback async methods with Task async methods?

I'm creating a service layer for my WPF app that will wrap a web API client that uses Action<T> callbacks for it's asynchronous methods. Since I'm going to need to wrap the methods anyway, I was considering making my wrapper methods of my service layer conform to the new Task-based async pattern of .NET 4.5, rather than expose Action<T> callbacks.
I don't currently have a pressing need for Task-based async, but I also don't have any reason that I necessarily have to stay with the callbacks and wrapping seems easy enough (as described here) Backwards compatibility isn't an issue. That said, if there are any pitfalls to such Action<T> callbacks to Tasks wrapping, I'll just maintain the status quo.
I do not see any pitfalls with doing this, in fact it opens your application to allot more flexible scenarios. I would suggest you also look at converting some of your "call back" scenarios to a the observer pattern (see Reactive Extensions project by Microsoft) which, when combined with the Task-based pattern, is so much more powerful and flexible. And of course you will be able to use your new new Task-based pattern with the new async/await-pattern in C# 5.0!
Hope it helps.

Async calls chaining in Metro app

I am quite new to Metro dev and I only hope I will be able to express my question in an understandable way...
Actually I am porting a part of my old application to Metro. The logic part is a separated project (Portable Library) and it should serve to 1) the old WPF app and 2) the new Metro app. The basic logic is the same but some subsystems (for example file operations manager) must be coded differently - i.e. async way for Metro.
My question is: Do I have to rewrite the whole chain of methods caller-callee to the new async paradigm? Let's say I have a chain of 4 methods, starting by method A = Metro UI event async handler (it makes sense to me to code it as async void as it is the top fire&forget event), through the next 2 methods (B and C) placed in different layers of my application, down to the method D containing "await CreateFileAsync" method (made async by Microsoft).
Now: async CreateFileAsync method should be called with await. That forces me to make method D async too. To call method D from C and C from B and B from A - do I have to rewrite all A, B and C into the async-await style?
I can feel I am missing a deeper knowledge so I am trying to educate myself but concurrently I wanted to try my luck here...
Do I have to rewrite a big part of my code? Is any of my statements above wrong?
Many thanks in advance, Hans
I recommend that you do rewrite your portable library to be asynchronous. It's not as bad as it used to be; Microsoft worked very hard on async/await to make it as easy as possible to convert synchronous code to asynchronous. I expect that a whole lot of others will be doing the same in the near future, and R# will probably implement a "make async" rewriting.
There are non-obvious pitfalls when mixing synchronous and asynchronous code - see Stephen Toub's last blog post Should I expose synchronous wrappers for asynchronous methods? For this reason, I think it's just cleaner to expose asynchronous operations as asynchronous APIs (and synchronous operations as synchronous APIs).
Update: If you do want synchronous code to call asynchronous code, then you can use the Task.WaitAndUnwrapException extension method in my AsyncEx library. However, you still have the problems mentioned in Stephen Toub's post, namely these:
You can deadlock if your library doesn't use ConfigureAwait(false) everywhere it can.
You can also deadlock if you run into the maximum number of threads in the thread pool.
(2) is not that common anymore, but (1) is a real possibility. It's regularly brought up by people who are just testing out async so they mix it with synchronous code.

Creating an async method in .NET 4.0 that can be used with "await" in .NET 4.5

I have a .NET project that uses C# in .NET 4.0 and VS2010.
What I would like to do is add some async overloads to my library to make doing async programming easier for users in .NET 4.5 with the await keyword. Right now the methods that are being overloaded are non-asynchronous. Also I don't want to use any async methods myself, just create new ones and make them available.
Is creating async methods in .NET 4.0 and VS2010 possible and if so, what should the .NET 4.0 async method look like?
Because I'm using VS2010 I don't have access to the "async" keyword so what needs to happen to emulate that behavior in .NET 4.0? For example does it need to return any particular type, and does any code need to happen inside the method to make the currently non-asynchronous code it is calling happen asynchronously?
As others have stated, you start by having a method return Task or Task<TResult>. This is sufficient to await its result in .NET 4.5.
To have your method fit in as well as possible with future asynchronous code, follow the guidelines in the Task-based Asynchronous Pattern document (also available on MSDN). It provides naming conventions and parameter recommendations, e.g., for supporting cancellation.
For the implementation of your method, you have a few choices:
If you have existing IAsyncResult-based asynchronous methods, use Task.Factory.FromAsync.
If you have another asynchronous system, use TaskCompletionSource<TResult>.
The simplest way to do this is to return a Task or a Task<T>. That will be enough.
However this only makes sense if your method really executes asynchronously.
I also recommend that you follow the usual pattern of naming them like AbcAsync ("Async" suffix). Your callers will not notice any difference to an async method created with C# 5 (because there is none).
Tip: Just adding async to the method does nothing. Your method will execute sequentially and return a completed task. Making the method return a task must serve a certain purpose - usually this is done because the method inherently executes asynchronously (like a web-service call or file IO).
If your method only contains computation but no IO (or only blocking IO) it is usually better not to make it async because you gain nothing doing that. Async methods do not always execute on a separate thread. If that last sentence surprised you, you may want to dig a little into this topic.
As long as you return a Task that completes somehow (whether in a thread or asynchronously), you would support the async model..
Having a Task execute asynchronously is another story. If you had access to the async keyword and the API you could simply base your method on async calls to other, already supplied async methods. But in this case, you have to hand-craft your async Tasks.
There might be better ways to do it, but the most elegant way I can see (and have used) is to utilize System.Threading.Tasks.TaskCompletionSource to construct a task, use Begin/End model of asynchronous methods to execute whatever you need to execute. Then, when you have the result on hand, post it to the previously constructed Task instance using your completion source.
It will certainly be asynchronous, just not as fancy as the ones in upcoming release.
Disclaimer: I'm no way near an expert on this. Just made some experiments on.

Is it a best practice to call methods asynchronously by using delegates?

This msdn article is entitled "How to call a Visual C# method asynchronously".
The article says "Asynchronous calls are made by using delegates" to which I reply in my head "not necessarily, that's only one way to do it".
The matter-of-fact tone of the articles statement makes me wonder - Is it a best practice, or does MS consider it a best practice, to use delegates when making asynchronous calls?
Up to the current .NET version, asynchronous methods have typically been handled in separate background threads from the one you trigger them from, so it's been mostly essential to do it using a delegate that you can invoke in another thread.
However, with the recent C# Async CTP (which will probably be in C# 5.0 or another future version), the story is changed a little - it's not essential to use delegates, you can write code in a traditional imperative style, and the compiler will do most of the work for you. This might involve delegates, but not necessarily - the compiler does some clever tricks and writes a finite state machine which can be used to execute code asynchronously.
Yes, delegates are the way to call methods asynchronously. It is not best practice, that is how it is done. In .NET, you must use a delegate.
Somebody can tell me im wrong please but i've been under the impression at compile time a delegate is as good as a method, the purpose of a delegate being a signature definition. I can think of no other way of executing async code without a method even if its anonymous which becomes a method at compile time..

Categories

Resources