So I'm writing a client API PCL (.NET 4.5, SL 5, Win8, WP8.1, WP SL 8) library and I've decided that I'm only going to allow one HTTP request at a time. Currently I use the TPL to do them:
Task.Factory.FromAsync<Stream>(httpReq.BeginGetRequestStream, httpReq.EndGetRequestStream, null).ContinueWith<Task<WebResponse>>((requestStreamTask) =>
{
return Task<WebResponse>.Factory.FromAsync(httpReq.BeginGetResponse, httpReq.EndGetResponse, null);
}).Unwrap().ContinueWith<HttpWebResponse>((getResponseTask) =>
{
return (HttpWebResponse)getResponseTask.Result;
});
So I want to add locking to prevent more than one request from going at once. I know I could simply call Monitor.Enter before I start and call Monitor.Exit in the last ContinueWith. But based on Migrating lock to TPL, I can't use Monitor like that because of threading issues possibly. I have no issue using a different blocking object like that post recommends but as far as I can tell in my PCL the only lock I have available is Monitor.
So what should I do?
EDIT: After talking with Yuval Itzchakov below I've realized the reason I only have the Monitor class for syncing is because I have Silverlight 5 support in my PCL. If there is no other way I'll look into dropping support for SL5 but I'd rather not.
EDIT2: After messing around I realized that I do have the ManualResetEvent class, could I use that?
Since you're writing a PCL and including some older platforms (specifically, SL5), your choices are a bit limited. TPL Dataflow is not supported on SL5, and neither is
SemaphoreSlim.However,
HttpClientis, and so areasync/await. These allow your code to be far, far cleaner thanTask.Factory.FromAsync+Unwrap+ContinueWith.For portable
async-ready synchronization and/or producer/consumer queues, I recommend my own AsyncEx library. In this case, anAsyncLockshould suffice; it can be used in a similar way toSemaphoreSlim: