4
\$\begingroup\$

Assuming I have to leave the contract intact (take byte[] and return byte[]), what's the correct way to structure this asynchronous method?

Will this deadlock running in ASP.NET in a web server thread?

public async Task<byte[]> CompressAsync(byte[] buffer)
{
    using (var outStream = new MemoryStream())
    {
        using (var tinyStream = new GZipStream(outStream, CompressionMode.Compress))
        using (var stream = new MemoryStream(buffer))
        {
            await stream.CopyToAsync(tinyStream);
        }

        return outStream.ToArray();
    }            
}
\$\endgroup\$
4
  • 3
    \$\begingroup\$ I think your last question is off-topic. We review working code here, while you are kind of asking us if your code works. \$\endgroup\$
    – Nikita B
    Nov 14, 2014 at 7:55
  • 1
    \$\begingroup\$ @NikitaBrizhak Disagreed, it is very hard to test for deadlocks. All asynchronous code can possibly go wrong, that does not mean all asynchronous code is not working. \$\endgroup\$
    – konijn
    Nov 14, 2014 at 18:19
  • \$\begingroup\$ @konijn, if asynchronous code can possibly "go wrong", than it does not work. \$\endgroup\$
    – Nikita B
    Nov 18, 2014 at 7:39
  • \$\begingroup\$ The code does work. I passes several unit and integration tests. The trick is that unless async and await are used throughout the pipeline, ASP.NET can deadlock. Most library code needs to use ConfigureAwait in order to ensure it works when an ASP.NET thread waits. It's mentioned in the answer below. I agree the statement that all asynchronous code can go wrong is basically solipsist. \$\endgroup\$
    – Jim
    Nov 18, 2014 at 11:20

1 Answer 1

2
\$\begingroup\$

I don't see any reason for the inner stream. Instead, you can just WriteAsync() the whole buffer directly into the (confusingly named) tinyStream.


Your code won't deadlock if used properly (i.e. asynchronously), but it will deadlock if someone synchronously waits for it (e.g. byte[] resultBuffer = CompressAsync(inputBuffer).Result;). To make sure this doesn't happen, add .ConfigureAwait(false) after every await.

You should do this for all your "library" code, that is code that doesn't need to run in the ASP.NET request context/GUI thread.


This method doesn't use any instance state. Why isn't it static?

\$\endgroup\$
3
  • \$\begingroup\$ I almost never use static methods for anything. This method is part of a larger class that implements an interface to ensure it can be doubled in unit and integration tests. I don't really have static methods anymore as everything needs tests. \$\endgroup\$
    – Jim
    Nov 18, 2014 at 11:26
  • \$\begingroup\$ @Jim You can test static methods just as easily as instance methods. Or are you talking about the difficulty of mocking them? \$\endgroup\$
    – svick
    Nov 18, 2014 at 12:48
  • \$\begingroup\$ I am talking about mocking, I mock out the compression and encryption in unit tests. \$\endgroup\$
    – Jim
    Nov 18, 2014 at 12:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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