A
APA
I've seen the MS sample async web request pattern and I ask is it really async if it is using a ManualResetEvent and setting WaitOne()? The
ManualResetEvent 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 ManualResetEvent 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 ManualResetEvent allDone = new ManualResetEvent(false);
const int BUFFER_SIZE = 1024;
public void WebReq(string URL, string somedata)
{
try
{
if (URL.Trim() != "")
{
byte[] data = Encoding.ASCII.GetBytes(somedata);
HttpWebRequest webRequest = (HttpWebRequest)System.Net.WebRequest.Create(URL);
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentLength = data.Length;
ManualResetEvent WaitHndle = new ManualResetEvent(false);
RequestState rs = new RequestState(WaitHndle,this.Debug);
rs.Request = webRequest;
rs.DataToSend = data;
webRequest.BeginGetRequestStream(new AsyncCallback(ReadCallbackRequest), rs);
IAsyncResult r = (IAsyncResult)webRequest.BeginGetResponse(new AsyncCallback(RespCallback), rs);
ThreadPool.RegisterWaitForSingleObject(r.AsyncWaitHandle, new WaitOrTimerCallback(ScanTimeoutCallback), rs, (30 * 1000), true);
allDone.WaitOne();
rs.ResponseStream.Close();
}
}
catch (WebException ex) { string str = ex.ToString(); }
catch (Exception ex) { string sr = ex.ToString(); }
}
private static void RespCallback(IAsyncResult ar)
{
RequestState rs = (RequestState)ar.AsyncState;
try
{
WebRequest req = rs.Request;
WebResponse resp = req.EndGetResponse(ar);
Stream ResponseStream = resp.GetResponseStream();
rs.ResponseStream = ResponseStream;
rs.Waitone.Set();
if (rs.Debug)
{
IAsyncResult iarRead = ResponseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs);
}
}
catch (Exception ex)
{
rs.Waitone.Set();
}
}
private static void ReadCallbackRequest(IAsyncResult asynchronousResult)
{
RequestState rs = (RequestState)asynchronousResult.AsyncState;
try
{
HttpWebRequest request = rs.Request;
Stream postStream = request.EndGetRequestStream(asynchronousResult);
postStream.Write(rs.DataToSend, 0, rs.DataToSend.Length);
postStream.Close();
}
catch (Exception ex)
{
}
allDone.Set();
}
private static void ScanTimeoutCallback(object state, bool timedOut)
{
if (timedOut)
{
RequestState reqState = (RequestState)state;
if (reqState != null)
reqState.Request.Abort();
}
}
public class RequestState
{
const int BufferSize = 1024;
public byte[] DataToSend;
public StringBuilder RequestData;
public byte[] BufferRead;
public HttpWebRequest Request;
public Stream ResponseStream;
public ManualResetEvent Waitone;
public bool Debug;
public Decoder StreamDecode = Encoding.UTF8.GetDecoder();
public RequestState(ManualResetEvent waitHandle,bool debug)
{
BufferRead = new byte[BufferSize];
RequestData = new StringBuilder(String.Empty);
Request = null;
ResponseStream = null;
Waitone = waitHandle;
Debug = debug;
}
}
}
ManualResetEvent 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 ManualResetEvent 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 ManualResetEvent allDone = new ManualResetEvent(false);
const int BUFFER_SIZE = 1024;
public void WebReq(string URL, string somedata)
{
try
{
if (URL.Trim() != "")
{
byte[] data = Encoding.ASCII.GetBytes(somedata);
HttpWebRequest webRequest = (HttpWebRequest)System.Net.WebRequest.Create(URL);
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentLength = data.Length;
ManualResetEvent WaitHndle = new ManualResetEvent(false);
RequestState rs = new RequestState(WaitHndle,this.Debug);
rs.Request = webRequest;
rs.DataToSend = data;
webRequest.BeginGetRequestStream(new AsyncCallback(ReadCallbackRequest), rs);
IAsyncResult r = (IAsyncResult)webRequest.BeginGetResponse(new AsyncCallback(RespCallback), rs);
ThreadPool.RegisterWaitForSingleObject(r.AsyncWaitHandle, new WaitOrTimerCallback(ScanTimeoutCallback), rs, (30 * 1000), true);
allDone.WaitOne();
rs.ResponseStream.Close();
}
}
catch (WebException ex) { string str = ex.ToString(); }
catch (Exception ex) { string sr = ex.ToString(); }
}
private static void RespCallback(IAsyncResult ar)
{
RequestState rs = (RequestState)ar.AsyncState;
try
{
WebRequest req = rs.Request;
WebResponse resp = req.EndGetResponse(ar);
Stream ResponseStream = resp.GetResponseStream();
rs.ResponseStream = ResponseStream;
rs.Waitone.Set();
if (rs.Debug)
{
IAsyncResult iarRead = ResponseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs);
}
}
catch (Exception ex)
{
rs.Waitone.Set();
}
}
private static void ReadCallbackRequest(IAsyncResult asynchronousResult)
{
RequestState rs = (RequestState)asynchronousResult.AsyncState;
try
{
HttpWebRequest request = rs.Request;
Stream postStream = request.EndGetRequestStream(asynchronousResult);
postStream.Write(rs.DataToSend, 0, rs.DataToSend.Length);
postStream.Close();
}
catch (Exception ex)
{
}
allDone.Set();
}
private static void ScanTimeoutCallback(object state, bool timedOut)
{
if (timedOut)
{
RequestState reqState = (RequestState)state;
if (reqState != null)
reqState.Request.Abort();
}
}
public class RequestState
{
const int BufferSize = 1024;
public byte[] DataToSend;
public StringBuilder RequestData;
public byte[] BufferRead;
public HttpWebRequest Request;
public Stream ResponseStream;
public ManualResetEvent Waitone;
public bool Debug;
public Decoder StreamDecode = Encoding.UTF8.GetDecoder();
public RequestState(ManualResetEvent waitHandle,bool debug)
{
BufferRead = new byte[BufferSize];
RequestData = new StringBuilder(String.Empty);
Request = null;
ResponseStream = null;
Waitone = waitHandle;
Debug = debug;
}
}
}