Pergunta

I'm trying to implement my HTTP responses to be fully asynchronous (with async/await).

This is a great simplification, but let's assume I have multiple small writes I need to make:

for (int i=0; i<1000; i++) WriteToResponse(words[i]);

A use-case for example is manual encoding objects to JSON or XML, and writing each object to the response as I encounter it during the object traversal.

My current implementation is:

async Task Respond(HttpResponse res)
{
    for (int i=0; i<1000; i++) await res.Output.WriteAsync(words[i]);
}

Is this the correct way to do this?

I'm a little worried that all the asynchronicity is adding a lot of overhead here. If I'm scheduling callbacks behind the scenes for every word I'm trying to write, maybe I should go ahead a write the whole thing synchronously?

When we were back in the synchronous days, I understood how buffering worked. I wrote to my output stream and it was actually buffered behind the scenes. When the buffer was full enough, it was flushed and actually written to the socket synchronously. But how does this work when I work asynchronously? Is it still buffered? Or am I actually waiting for the completion of every small write before I make the next one?

Foi útil?

Solução

I would expect the buffering to be independent of the synchronicity - so while it's buffering, "asynchronous" writes are likely to actually complete synchronously (because it's just in memory), at which point it's really, really cheap to await.

When the buffer gets big enough, it will start writing to the socket, at which point the await really will be asynchronous with an extra (small) hit.

However, I'd suggest that you can make your code simpler anyway by just joining the words together and then performing a single write. You already have all the data, after all - it's not like you'd be waiting for some of it.

At that point, you'll only have one asynchronous call, so you don't even need to use await:

Task Respond(HttpResponse res)
{
    string data = string.Join("", words.Take(1000)); // Or whatever
    return res.Output.WriteAsync(data);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top