0

I am reading from a GzipStream which wraps a NetworkStream in a UI event handler.

using (var gzipStream = new GzipStream(networkStream, CompressionMode.Decompress) {
    await WriteSomethingToStream(gzipStream);
}

The DeflateStream which the GzipStream wraps has a blocking Write call in it's Dispose method for flushing the buffer.
So at the end of Using statement, gzipStream.Dispose() blocks, and UI will block.

There is no GzipStream.DisposeAsync/CloseAsync() method either.

So how do I not block while disposing? FlushAsync doesn't work because according to it's(Flush) documentation, it does nothing.

The current implementation of this method does not flush the internal buffer. The internal buffer is flushed when the object is disposed.

wingerse
  • 3,670
  • 1
  • 29
  • 61
  • What about wrapping whole `using` statement with `await Task.Run(() => using(...) {...} )`? – Ňuf Sep 14 '17 at 19:11
  • 1
    @Ňuf I am actually using this in a server and used UI example to make the question easier. So using Task.Run will use a whole thread which is not desired. – wingerse Sep 14 '17 at 19:18
  • But you don't have much choice here - calling synchronous method asynchronously always needs thread. `Task.Run()` uses threadpool thread, so overhead should be quite small. Other choices are IMHO much worse: You can either write your own implementation of `GZipStream` with proper implementation of `FlushAsync()`, or "hack" current `GZipStream` implementation using reflection to access it's private members and flush internal buffers asynchronously (which is evil because it relies on implementation details of GZipStream class, which is subject to change). – Ňuf Sep 14 '17 at 20:17
  • @Ňuf augh. It's a shame they don't implement Flush and instead shoves it into Dispose method.. Thanks for the help :) I'm thinking of using a memory stream in the middle and then using CopyToAsync to the network stream :) – wingerse Sep 15 '17 at 08:37

0 Answers0