Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way in C# to make a call to an async method without making the caller also async? [duplicate]

To be clearer, I am referencing a factory method that did not used to be async. In a recent API upgrade, they made the old method obsolete and created a new async method. Now, our code base is originally from VS2010 when async did not yet exist. I would like to change the method call to the new version so that we don't throw deprecation warnings.

Now onto the problem: Any call to an async method seems to require an "await" in order to guarantee that the method actually completed and that any state data initialized in that method is available for subsequent operations. However, putting an "await" in the call requires that the calling method also be async, which then requires that the caller of that method also use an await, and so forth all the way up to the top of the call stack. The only way I've found to avoid this is to put the call to the async factory method in a void async method. However, Microsoft has specifically stated that that functionality only exists for event handlers and should be avoided otherwise.

Now, it's true that I could adjust every single function in the call stack. But that's not only irritating to deal with, but is also an extreme encapsulation violation. Why should a top-level class have to be changing its method headers just because some call to a function 27 layers down had to deal with an external API change? I suspect that I'm missing something very obvious, but from what it looks like, I have two options: Either change all the method headers or submit to a "bad programming practice." Is there another way? Thanks in advance for any input.

like image 822
C. Williamson Avatar asked Oct 30 '22 23:10

C. Williamson


1 Answers

Is there another way?

Not really. Either the function call is synchronous (by definition, blocking the thread), or a function call is asynchronous (by definition, not blocking the thread). It's not possible to have a thread blocked and not blocked at the same time.

I recommend you upgrade your code to use async. This is the best long-term solution. Or, you could turn the obsolete warning off, or stay with an older version of your library.

That said, I did write an article on brownfield async development, which illustrates a variety of partially-async approaches and the drawbacks to each (spoiler: there is no perfect solution).

like image 197
Stephen Cleary Avatar answered Nov 15 '22 05:11

Stephen Cleary