I've seen the MS sample async web request pattern and I ask is it really async if it is using a ManualResetEven t and setting WaitOne()? The
ManualResetEven t object is being declared as a static variable so isn't it causing problems with other threads that may be using the same class to
execute the async web request? If I remove the ManualResetEven t object will it be truly asynchronous and will I be losing something? Also, in my app
the web request is posting data.
For those that haven't seen the code it looks something like this:
public class AsyncWebRequest
public AsyncWebRequest (){}
public static ManualResetEven t allDone = new ManualResetEven t(false);
const int BUFFER_SIZE = 1024;
public void WebReq(string URL, string somedata)
{
try
{
if (URL.Trim() != "")
{
byte[] data = Encoding.ASCII. GetBytes(someda ta);
HttpWebRequest webRequest = (HttpWebRequest )System.Net.Web Request.Create( URL);
webRequest.Meth od = "POST";
webRequest.Cont entType = "applicatio n/x-www-form-urlencoded";
webRequest.Cont entLength = data.Length;
ManualResetEven t WaitHndle = new ManualResetEven t(false);
RequestState rs = new RequestState(Wa itHndle,this.De bug);
rs.Request = webRequest;
rs.DataToSend = data;
webRequest.Begi nGetRequestStre am(new AsyncCallback(R eadCallbackRequ est), rs);
IAsyncResult r = (IAsyncResult)w ebRequest.Begin GetResponse(new AsyncCallback(R espCallback), rs);
ThreadPool.Regi sterWaitForSing leObject(r.Asyn cWaitHandle, new WaitOrTimerCall back(ScanTimeou tCallback), rs, (30 * 1000), true);
allDone.WaitOne ();
rs.ResponseStre am.Close();
}
}
catch (WebException ex) { string str = ex.ToString(); }
catch (Exception ex) { string sr = ex.ToString(); }
}
private static void RespCallback(IA syncResult ar)
{
RequestState rs = (RequestState)a r.AsyncState;
try
{
WebRequest req = rs.Request;
WebResponse resp = req.EndGetRespo nse(ar);
Stream ResponseStream = resp.GetRespons eStream();
rs.ResponseStre am = ResponseStream;
rs.Waitone.Set( );
if (rs.Debug)
{
IAsyncResult iarRead = ResponseStream. BeginRead(rs.Bu fferRead, 0, BUFFER_SIZE, new AsyncCallback(R eadCallBack), rs);
}
}
catch (Exception ex)
{
rs.Waitone.Set( );
}
}
private static void ReadCallbackReq uest(IAsyncResu lt asynchronousRes ult)
{
RequestState rs = (RequestState)a synchronousResu lt.AsyncState;
try
{
HttpWebRequest request = rs.Request;
Stream postStream = request.EndGetR equestStream(as ynchronousResul t);
postStream.Writ e(rs.DataToSend , 0, rs.DataToSend.L ength);
postStream.Clos e();
}
catch (Exception ex)
{
}
allDone.Set();
}
private static void ScanTimeoutCall back(object state, bool timedOut)
{
if (timedOut)
{
RequestState reqState = (RequestState)s tate;
if (reqState != null)
reqState.Reques t.Abort();
}
}
public class RequestState
{
const int BufferSize = 1024;
public byte[] DataToSend;
public StringBuilder RequestData;
public byte[] BufferRead;
public HttpWebRequest Request;
public Stream ResponseStream;
public ManualResetEven t Waitone;
public bool Debug;
public Decoder StreamDecode = Encoding.UTF8.G etDecoder();
public RequestState(Ma nualResetEvent waitHandle,bool debug)
{
BufferRead = new byte[BufferSize];
RequestData = new StringBuilder(S tring.Empty);
Request = null;
ResponseStream = null;
Waitone = waitHandle;
Debug = debug;
}
}
}
ManualResetEven t object is being declared as a static variable so isn't it causing problems with other threads that may be using the same class to
execute the async web request? If I remove the ManualResetEven t object will it be truly asynchronous and will I be losing something? Also, in my app
the web request is posting data.
For those that haven't seen the code it looks something like this:
public class AsyncWebRequest
public AsyncWebRequest (){}
public static ManualResetEven t allDone = new ManualResetEven t(false);
const int BUFFER_SIZE = 1024;
public void WebReq(string URL, string somedata)
{
try
{
if (URL.Trim() != "")
{
byte[] data = Encoding.ASCII. GetBytes(someda ta);
HttpWebRequest webRequest = (HttpWebRequest )System.Net.Web Request.Create( URL);
webRequest.Meth od = "POST";
webRequest.Cont entType = "applicatio n/x-www-form-urlencoded";
webRequest.Cont entLength = data.Length;
ManualResetEven t WaitHndle = new ManualResetEven t(false);
RequestState rs = new RequestState(Wa itHndle,this.De bug);
rs.Request = webRequest;
rs.DataToSend = data;
webRequest.Begi nGetRequestStre am(new AsyncCallback(R eadCallbackRequ est), rs);
IAsyncResult r = (IAsyncResult)w ebRequest.Begin GetResponse(new AsyncCallback(R espCallback), rs);
ThreadPool.Regi sterWaitForSing leObject(r.Asyn cWaitHandle, new WaitOrTimerCall back(ScanTimeou tCallback), rs, (30 * 1000), true);
allDone.WaitOne ();
rs.ResponseStre am.Close();
}
}
catch (WebException ex) { string str = ex.ToString(); }
catch (Exception ex) { string sr = ex.ToString(); }
}
private static void RespCallback(IA syncResult ar)
{
RequestState rs = (RequestState)a r.AsyncState;
try
{
WebRequest req = rs.Request;
WebResponse resp = req.EndGetRespo nse(ar);
Stream ResponseStream = resp.GetRespons eStream();
rs.ResponseStre am = ResponseStream;
rs.Waitone.Set( );
if (rs.Debug)
{
IAsyncResult iarRead = ResponseStream. BeginRead(rs.Bu fferRead, 0, BUFFER_SIZE, new AsyncCallback(R eadCallBack), rs);
}
}
catch (Exception ex)
{
rs.Waitone.Set( );
}
}
private static void ReadCallbackReq uest(IAsyncResu lt asynchronousRes ult)
{
RequestState rs = (RequestState)a synchronousResu lt.AsyncState;
try
{
HttpWebRequest request = rs.Request;
Stream postStream = request.EndGetR equestStream(as ynchronousResul t);
postStream.Writ e(rs.DataToSend , 0, rs.DataToSend.L ength);
postStream.Clos e();
}
catch (Exception ex)
{
}
allDone.Set();
}
private static void ScanTimeoutCall back(object state, bool timedOut)
{
if (timedOut)
{
RequestState reqState = (RequestState)s tate;
if (reqState != null)
reqState.Reques t.Abort();
}
}
public class RequestState
{
const int BufferSize = 1024;
public byte[] DataToSend;
public StringBuilder RequestData;
public byte[] BufferRead;
public HttpWebRequest Request;
public Stream ResponseStream;
public ManualResetEven t Waitone;
public bool Debug;
public Decoder StreamDecode = Encoding.UTF8.G etDecoder();
public RequestState(Ma nualResetEvent waitHandle,bool debug)
{
BufferRead = new byte[BufferSize];
RequestData = new StringBuilder(S tring.Empty);
Request = null;
ResponseStream = null;
Waitone = waitHandle;
Debug = debug;
}
}
}