4

I'm creating a library that contains a class that exposes several Async methods:

public class MyClass {
  public async Task<Foo> DoFooAsync() { /*...*/ }
  public async Task<Bar> DoBarAsync() { /*...*/ }
}

I have two (main) questions about this:

  1. I understand that not everybody likes to (or needs to) work asynchronously; it's easy for someone using my library to invoke these methods synchronously. However, it won't be very much of an effort to provide synchronous wrappers for the async method so that the class also provides a public Foo DoFoo() and public Bar DoBar() method.

    • Should I provide these methods or should I let people implement their own?
    • If I provide these methods, should I:
      1. Create a private T ExecuteFunctionSynchronously<T>(Func<T> func) method and have the synchronous methods invoke this ExecuteFunctionSynchronously internally or ...
      2. ...should every synchronous method just call the async method 'waterfall style' (so DoFoo() executes return DoFooAsync().Result (or something like that) internally?
  2. The class will, later, have a 'message loop' which continually reads data coming from an (awaited) socket. I want this message loop to go on 'eternally'. I want the class to be easily used by everyone.

    • What kind of 'style' should I use for this messageloop to notify users of MyClass that something has happened?
      1. Events (e.g. MyClass.FooReceived += myhandler)?
      2. Callbacks (e.g. MyClass.StartListening(myhandler))?
      3. Something 'awaitable' (e.g. while (await MyClass.GetFoo()) { ... })?
      4. Reactive (Rx)?
      5. Something other than above, namely ...

I'm primarily asking for "style" guidance; how would you approach this and how do you think a (primarily) async library should provide (API wise) interaction while keeping internals and messageloops out of the user's mind without exposing too much of what's going on internally.

2 Answers 2

3

Should I provide these methods or should I let people implement their own?

You should avoid doing that. Stephen Toub explains why in his article Should I expose synchronous wrappers for asynchronous methods? The reason why is that doing this has quite a few pitfalls, simple .Result may appear to work for you, but may fail (or rather, deadlock) in other situations.

What kind of 'style' should I use for this messageloop to notify users of MyClass that something has happened?

I think that depends on what kind of notifications are you exposing, what will your users want to do with them and what will feel most natural to them. There is a reason why all of those different styles exist.

0

Should I provide these methods or should I let people implement their own?

I'm trying to find the post (I think it was Stephen Cleary on SO), but one of the answers had made the point that he preferred to make his operations synchronous and let the client decide if they want to call them asynchronously or not.

It stuck with me because it was Stephen Cleary and I liked the idea that your code can be used in the same old way without having to think about it, or it can be wrapped in an async wrapper, which requires a bit more thought but it's work you're choosing to take on.

This, versus the opposite situation where you have to think about and put more effort into using a library in the standard synchronous way we're generally used to.

Not the answer you're looking for? Browse other questions tagged or ask your own question.