Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
115 views
in Technique[技术] by (71.8m points)

c# - Interfaces and async practices

I have an interface

public interface IUserFactory
{
       User GetUser(string id);
       void DeleteUser(string id);
}

Current class which implements uses functions which are synchronous.

I am now going to have an implementation which uses HttpClient, whose calls are async.

What I’m doing now is to have the new UserFactoryWeb class implement two sets of functions:

Task<User> GetUserAsync(string id)
Task DeleteUserAsync(string id)

and

User GetUser(string id)
void DeleteUser(string id)

the interface methods. In the interface methods I use the trick:

var t = Task.Run(async code...)
t.Wait();

in order to prevent deadlocks.

Are there other options?

Also, how can you support async calls in interfaces? It seems crazy that async isnt part of an interface signature.

question from:https://stackoverflow.com/questions/65947264/interfaces-and-async-practices

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Let's rationalise why interfaces don't need the async keyword

  1. A Method returning a Task / ValueTask does not need to be an Async Method (a method with the async keyword).
  2. An Async Method is basically compiler plumbing to help with
    1. The return Task / ValueTask (when not void),
    2. Placing exceptions on a returned Task / ValueTask (when not void)
    3. Allowing the use of the await keyword
  3. An Async Method runs synchronously until it hits the first await expression, at which point the method is suspended until the awaited task is complete.
  4. An Async Method does not need an await, in which case it’s just compiler plumbing for the return value and exception when not void (see point 1.1 and 1.2 respectively)
  5. You can use await on anything the supports the INotifyCompletion and the return type exposes 3 members
    • IsCompleted
    • OnCompleted
    • GetResult
  6. Task and ValueTask can be awaited regardless of whether they were returned by an Async Method (see point 5)
  7. Interfaces are just contracts between the implementer and the caller and give no indication of how the contract is implemented, they just contain definitions for a group of related functionalities
  8. The definition of such members need no guaranteed on whether the method has been plumbed up with an async keyword (or whatever funky things you do in that method) just that that it returns a Task / ValueTask

In short the async keyword is an implementation detail, the contract is just a definition, the definition doesn’t care what you do in your method. However, if you do, or you would like your callers to know this, you document well.

To prove this, the async keyword has no actual bearing on the compilation of a method signature or how the callee invokes it. Let's look at the compiled code here. You will notice the method actually loses the async keyword and just returns a task. However, the compiler does to a lot of other plumbing to implement the language feature.

A method such as

public static async Task Test1()

Is actually compiled to

[AsyncStateMachine(typeof(<Test1>d__0))]
public static Task Test1()

Additional Resources


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...