A Simple MultiThreading Pattern For C# With No Statics. Shows Compressing A File With GZip

Posted by Peter Kellner on December 04, 2010 · 5 mins read

Background

This post shows a very simple technique for processing a gzip compression on a background thread using c# with Visual Studio 2010.  What is unique here is we are using no statics to do it.  I’m not totally against using statics, but in general, it is best to avoid them.  I’ve heard the notorious Ward Bell say statics are evil and have had many cases where they have bitten me.  Since I heard Ward say this, I’ve been trying to avoid them where I can.

 

The Simple Problem

The problem is to simply compress a file to bytes and return to us the compressed, uncompressed and byte array of the result.  We can pass parameters into a thread, however we can not return them (when I say thread, I mean the anonymous method that processes our data).


Some Code

So, to that end, Let’s create a main method as below.  Notice that it creates a very simple anonymous method which executes the code cryptoCopress.CompressFile(…), then simply starts that thread.  Once the thread starts, it simply waits for the thread to end by looping every 50 milliseconds on the thread.IsAlive method.  Finally, when it returns, it simply looks at the cryptCompress object for the results.  No Statics!

 

private static void Main(string[] args)
{
var cryptCompress =
new CryptCompress();
var thread =
new Thread(
() =>
cryptCompress.CompressFile
(@"G:\NoBackup\ext-3.2.1\ext-all-debug-w-comments.js"));
thread.Start();

int cnt = 0;
while (thread.IsAlive)
{
cnt++;
Console.WriteLine("Waiting... " + cnt);
Thread.Sleep(50);
}
Console.WriteLine("Before Compression KBytes: {0}",
cryptCompress.BeforeCompressionBytes/1000);
Console.WriteLine("After Compression KBytes: {0}",
cryptCompress.AfterCompressionBytes/1000);
}

Now, Lets look at the CryptCompress class.  Notice that it’s basically got one public method (CompressFile) and 3 public properties that will be used to hold the return values.  This way, the main method that started the thread can get the results.  Again, notice that there is no word static any place in this project.

public class CryptCompress
{
public byte[] CompressedBytes { get; set; }
public long BeforeCompressionBytes { get; set; }
public long AfterCompressionBytes { get; set; }

public void CompressFile(string fileName)
{
using (var fileStream =
new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
var uncompressedBytes = new byte[fileStream.Length];
fileStream.Read(uncompressedBytes, 0,
(int) fileStream.Length);
CompressedBytes = CompressGzip(uncompressedBytes);
BeforeCompressionBytes = fileStream.Length;
AfterCompressionBytes = CompressedBytes.Length;
fileStream.Close();
}
}

/// <summary>
/// Take a simple stream of uncompressed bytes and compress them
/// </summary>
/// <param name="uncompressedBytes"></param>
/// <returns></returns>
public byte[] CompressGzip(byte[] uncompressedBytes)
{
using (var memory = new MemoryStream())
{
using
(var gZipStream =
new GZipStream(memory, CompressionMode.Compress, true))
{
gZipStream.Write
(uncompressedBytes, 0, uncompressedBytes.Length);
}
return memory.ToArray();
}
}
}

 

The Results

When we run this, notice that it takes 3 iterations (or 150 milliseconds) to complete. I’m only compressing a small file so no surprise.  The file is actually 2.7 Megabytes and compress to .7 Megabytes.

image

 

That’s it for now! Hope this helps.