Using WMSTools
//select WMS server
var svrURL = @"http://geo.weather.gc.ca/geomet/?";
var server = new Server(svrURL);
// load capabilities
var f = await server.LoadData();
var cap = server.Capabilities;
var fLayer = cap.Layers.First();
var layers = fLayer.Layers;

var lat = 45.421780;
var lon = -75.691177;
// select layer by lat, lon and name
var wind = fLayer.FindBy(cl => cl.Name != null && cl.Name.StartsWith("HRDPS.") && cl.Name.EndsWith("_UU"), lat, lon, lat, lon).Single();

// images
var w = 512;
var h = 512;
// calculate current time
var dt = DateTime.Now;
var hour = dt.Hour;
if (dt.Minute > 30)
{
    hour++;
}
var fDt = dt.Date;
fDt = fDt.AddHours(hour);

var bb = new WMSLib.Client.Layer.BoundingBoxType() { MinX = -74.6346271171326, MinY = 46.22741707027332, MaxX = -72.87694133662491, MaxY = 47.26928933489761 };
// this generates a list of URL + timestamps
var uris = wind.BuildAllURLs(w, h, bb);
// now read the images
// this is multithreaded
var cts = new CancellationTokenSource();
// the last argument is a function that returns a native bitmap from a stream
// the Subject (reactive libs) is used for reporting loading progress
var b = await WMSUtils.ReadAllImages(cts.Token, new Subject<int>(), w, h, uris, async s => new Bitmap(s));