简体   繁体   中英

Can you call an async web api controller method synchronously?

Let's say I have a webservice with the following API controller method:

public async Task<ActionResult<string>> Get()
{
   await Task.Delay(1000);
   return Ok("Success");
}

It seems like I can call this api controller method synchronously like such

var url = "http://example.com/api/example";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.Method = "GET";

string webStringResult;
using (HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse())
{
    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
    {
      var result = streamReader.ReadToEnd();
      webStringResult= JsonConvert.DeserializeObject<string>(result);
    }
}

I was shocked that this works. I thought that I would have to be forced to use httpWebRequest.GetResponseAsync()

But it seems like httpWebRequest.GetResponse() also works.

My question is, if this is correct workflow and what the implications are of using GetResponse() with an async web method versus GetResponseAsync() . Normally if you're calling an async method directly from another library/class you must be calling it from an async method and you have to await it. However, making a web request is a little different since you're not technically directly calling the method. So I was surprised to see that this worked and it would help to know the implications/understanding of what is going on here.

Normally if you're calling an async method directly from another library/class you must be calling it from an async method and you have to await it.

Yes, within the same process .

However, making a web request is a little different since you're not technically directly calling the method.

Right. The client isn't calling the server method at all. It's making an HTTP request to a server. The server application handles that HTTP request by invoking the server method.

Since these are different processes, the server doesn't care whether the client is synchronous or asynchronous; and the client doesn't care whether the server is synchronous or asynchronous. They're both just talking over the.network.

if this is correct workflow and what the implications are of using GetResponse() with an async web method versus GetResponseAsync().

GetResponse just means your client is synchronous. I'd say it would technically be more proper as an asynchronous method, since it is I/O-based, but if you're fine with a synchronous client, then that's totally fine.

One way to think about it is to assume that the client and the server are written in different languages and the server code was written 20 years ago. They can work together because they use the same protocol (http in this case) and not because they are written in the same version of a language.

Having said that, please note that this separation - achieved by using the http protocol - is true even if you running both on the same machine, and even as part of the same process. For example, in a test, you could start a web server and make http calls to it, async or not, from the same program.

Another way to think about it is to imagine that the client and server use a 'file protocol': if the client wants work done it drops a file with json in a special folder; the sever monitors this folder reads the file and later saves the response as 'response.json'. The client could write the file with await File.WriteAllTextAsync and the server could read the file with File.ReadAllText (not async).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM