By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,079 Members | 901 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,079 IT Pros & Developers. It's quick & easy.

Why is this HttpWebRequest class unreliable?

P: n/a
Hi,

Could someone please give me some suggestions on how to make this class
robust. I need to be able to handle around 20 similtanious requests to
this class which causes a web browser to display a waiting message
while it requests XML data from a third party server. Some requests can
take around 30 seconds.

Usually the first time I do the request it always works. If I try again
without closing the web browser it will fail sometimes. And if I try
from more than 1 web browser at the same time it will fail a lot.

bool CheckAvailable() is used for the requests.

Thanks
using System;
using System.Xml;
using System.Net;
using System.IO;
using System.Text;
using System.Threading;

namespace TestPost
{
/// <summary>
/// Summary description for SamplePost.
/// </summary>
public class SamplePost
{
public static AutoResetEvent m_allDone = null;

public SamplePost()
{
}

private bool CheckAvailable(string strURL, string strXMLPost,string
strUser, string strPassword)
{
// send POST request
m_strURL = strURL;
m_strXMLPost = strXMLPost;
m_strUser = strUser;
m_strPassword = strPassword;

RequestState myRequestState = null;
// send POST request
try
{
// Create a new 'HttpWebRequest' object to the mentioned URL.
HttpWebRequest myHttpWebRequest1 =
(HttpWebRequest)WebRequest.Create(m_strURL);
myRequestState = new RequestState();
myRequestState.request = myHttpWebRequest1;
myRequestState.m_strPostData = m_strXMLPost;
myHttpWebRequest1.ContentType =
"application/x-www-form-urlencoded";
myHttpWebRequest1.Method = "POST";
myHttpWebRequest1.Headers.Add("Cache-Control","no-cache");
myHttpWebRequest1.ContentLength = m_strXMLPost.Length;
myHttpWebRequest1.KeepAlive = true;
myHttpWebRequest1.Credentials = new
NetworkCredential(m_strUser,m_strPassword);

m_allDone = new AutoResetEvent(false);
IAsyncResult result = (IAsyncResult)
myHttpWebRequest1.BeginGetRequestStream(new
AsyncCallback(PostCallback),myRequestState);
// using result.AsyncWaitHandle slips past WaitOne, so trying
threadpool
// result.AsyncWaitHandle.WaitOne(20000,true);
ThreadPool.RegisterWaitForSingleObject (result.AsyncWaitHandle, new
WaitOrTimerCallback(TimeoutSocketCallback), myHttpWebRequest1,
DefaultTimeout, true);
m_allDone.WaitOne();

if(!myRequestState.m_bResultOK)
return false;

// Start the asynchronous BeginGetResponse request.
m_allDone = new AutoResetEvent(false);
IAsyncResult result2 = (IAsyncResult)
myHttpWebRequest1.BeginGetResponse(new
AsyncCallback(RespCallback),myRequestState);
ThreadPool.RegisterWaitForSingleObject (result2.AsyncWaitHandle,
new WaitOrTimerCallback(TimeoutSocketCallback), myHttpWebRequest1,
Defines.N_HTTP_REQUEST_TIMEOUT, true);
m_allDone.WaitOne();
myRequestState.response.Close();
}
catch(WebException)
{
return false;
}
catch(Exception)
{
return false;
}
// check reply OK
bool bOK = false;
if(myRequestState != null)
{
string strReply = myRequestState.m_strReply;
bOK = VerifyXMLReply(strReply);
}
return bOK;
}

// send post data
private void PostCallback(IAsyncResult asynchronousResult)
{
RequestState myRequestState = null;
try
{
// Set the State of request to asynchronous.
myRequestState = (RequestState)asynchronousResult.AsyncState;
HttpWebRequest myHttpWebRequest2 =
(HttpWebRequest)myRequestState.request;
// End of the Asynchronus writing .
Stream postStream =
myHttpWebRequest2.EndGetRequestStream(asynchronous Result);
// send any post data
if(!Helpers.IsEmpty(myRequestState.m_strPostData))
{
ASCIIEncoding encoder = new ASCIIEncoding();
// Convert the string into byte array.
byte[] ByteArray = encoder.GetBytes(myRequestState.m_strPostData);
// Write to the stream.
postStream.Write(ByteArray,0,myRequestState.m_strP ostData.Length);
}
postStream.Close();
myRequestState.m_bResultOK = true;
m_allDone.Set();
}
catch(WebException e)
{
if(myRequestState != null)
{
myRequestState.m_strErrorText = e.Message;
myRequestState.m_bResultOK = false;
}
}
catch(Exception e)
{
if(myRequestState != null)
{
myRequestState.m_strErrorText = e.Message;
myRequestState.m_bResultOK = false;
}
}
m_allDone.Set();
}

// read response
private void RespCallback(IAsyncResult asynchronousResult)
{
RequestState myRequestState = null;
try
{
// State of request is asynchronous.
myRequestState = (RequestState) asynchronousResult.AsyncState;
HttpWebRequest myHttpWebRequest = myRequestState.request;
myRequestState.response = (HttpWebResponse)
myHttpWebRequest.EndGetResponse(asynchronousResult );
// Read the response into a Stream object.
Stream responseStream =
myRequestState.response.GetResponseStream();
myRequestState.streamResponse = responseStream;
// Begin the Reading of the contents of the HTML page and print it
to the console.
IAsyncResult asynchronousInputRead =
responseStream.BeginRead(myRequestState.BufferRead , 0, BUFFER_SIZE, new
AsyncCallback(ReadCallBack), myRequestState);
return;
}
catch(WebException e)
{
if(myRequestState != null)
{
myRequestState.m_bResultOK = false;
myRequestState.m_strErrorText = e.Message;
}
}
m_allDone.Set();
}

// read callback
private void ReadCallBack(IAsyncResult asyncResult)
{
RequestState myRequestState = null;
try
{
myRequestState = (RequestState)asyncResult.AsyncState;
Stream responseStream = myRequestState.streamResponse;
int read = responseStream.EndRead(asyncResult);
// Read the HTML page and then print it to the console.
if (read > 0)
{
myRequestState.m_strReply +=
Encoding.ASCII.GetString(myRequestState.BufferRead , 0, read);
IAsyncResult asynchronousResult = responseStream.BeginRead(
myRequestState.BufferRead, 0, BUFFER_SIZE, new
AsyncCallback(ReadCallBack), myRequestState);
return;
}
else
{
myRequestState.m_bResultOK = true;
responseStream.Close();
}
}
catch(WebException e)
{
if(myRequestState != null)
{
myRequestState.m_bResultOK = false;
myRequestState.m_strErrorText = e.Message;
}
}
m_allDone.Set();
}

// Abort the request if the timer fires.
private void TimeoutSocketCallback(object state, bool timedOut)
{
if(timedOut)
{
HttpWebRequest request = state as HttpWebRequest;
if (request != null)
{
request.Abort();
}
}
}
}

// used for asyncronous requests
public class RequestState
{
// This class stores the State of the request.
const int BUFFER_SIZE = 1024;
public string m_strPostData;
public string m_strReply;
public string m_strErrorText;
public bool m_bResultOK;
public byte[] BufferRead;
public HttpWebRequest request;
public HttpWebResponse response;
public Stream streamResponse;
// constructor
public RequestState()
{
BufferRead = new byte[BUFFER_SIZE];
request = null;
streamResponse = null;
m_bResultOK = false;
m_strPostData = "";
m_strErrorText = "";
m_strReply = "";
}
}
}

Nov 19 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a
Hi sfoxover:

You have several threading issues in this code. For example,
declaring AutoResetEvent as a static member is begging for your
threads to miss the signal entirely.

My suggestion would be to get rid of all the asynch activity - it's
not buying you anything in this code. The original thread is doing
nothing but waiting for the second thread to finish - so why not skip
the 2nd thread and do all the work with 1?

Try to get it working first, and then see if you need to make some
optimizations.

You'll also want to bump up the number of HTTP connections you can
make to an external machine:
http://odetocode.com/Blogs/scott/arc...06/08/272.aspx

--
Scott
http://www.OdeToCode.com/blogs/scott/

On 11 Jul 2005 23:27:55 -0700, sf******@gmail.com wrote:
Hi,

Could someone please give me some suggestions on how to make this class
robust. I need to be able to handle around 20 similtanious requests to
this class which causes a web browser to display a waiting message
while it requests XML data from a third party server. Some requests can
take around 30 seconds.

Usually the first time I do the request it always works. If I try again
without closing the web browser it will fail sometimes. And if I try
from more than 1 web browser at the same time it will fail a lot.

bool CheckAvailable() is used for the requests.

Thanks
using System;
using System.Xml;
using System.Net;
using System.IO;
using System.Text;
using System.Threading;

namespace TestPost
{
/// <summary>
/// Summary description for SamplePost.
/// </summary>
public class SamplePost
{
public static AutoResetEvent m_allDone = null;

public SamplePost()
{
}

private bool CheckAvailable(string strURL, string strXMLPost,string
strUser, string strPassword)
{
// send POST request
m_strURL = strURL;
m_strXMLPost = strXMLPost;
m_strUser = strUser;
m_strPassword = strPassword;

RequestState myRequestState = null;
// send POST request
try
{
// Create a new 'HttpWebRequest' object to the mentioned URL.
HttpWebRequest myHttpWebRequest1 =
(HttpWebRequest)WebRequest.Create(m_strURL);
myRequestState = new RequestState();
myRequestState.request = myHttpWebRequest1;
myRequestState.m_strPostData = m_strXMLPost;
myHttpWebRequest1.ContentType =
"application/x-www-form-urlencoded";
myHttpWebRequest1.Method = "POST";
myHttpWebRequest1.Headers.Add("Cache-Control","no-cache");
myHttpWebRequest1.ContentLength = m_strXMLPost.Length;
myHttpWebRequest1.KeepAlive = true;
myHttpWebRequest1.Credentials = new
NetworkCredential(m_strUser,m_strPassword);

m_allDone = new AutoResetEvent(false);
IAsyncResult result = (IAsyncResult)
myHttpWebRequest1.BeginGetRequestStream(new
AsyncCallback(PostCallback),myRequestState);
// using result.AsyncWaitHandle slips past WaitOne, so trying
threadpool
// result.AsyncWaitHandle.WaitOne(20000,true);
ThreadPool.RegisterWaitForSingleObject (result.AsyncWaitHandle, new
WaitOrTimerCallback(TimeoutSocketCallback), myHttpWebRequest1,
DefaultTimeout, true);
m_allDone.WaitOne();

if(!myRequestState.m_bResultOK)
return false;

// Start the asynchronous BeginGetResponse request.
m_allDone = new AutoResetEvent(false);
IAsyncResult result2 = (IAsyncResult)
myHttpWebRequest1.BeginGetResponse(new
AsyncCallback(RespCallback),myRequestState);
ThreadPool.RegisterWaitForSingleObject (result2.AsyncWaitHandle,
new WaitOrTimerCallback(TimeoutSocketCallback), myHttpWebRequest1,
Defines.N_HTTP_REQUEST_TIMEOUT, true);
m_allDone.WaitOne();
myRequestState.response.Close();
}
catch(WebException)
{
return false;
}
catch(Exception)
{
return false;
}
// check reply OK
bool bOK = false;
if(myRequestState != null)
{
string strReply = myRequestState.m_strReply;
bOK = VerifyXMLReply(strReply);
}
return bOK;
}

// send post data
private void PostCallback(IAsyncResult asynchronousResult)
{
RequestState myRequestState = null;
try
{
// Set the State of request to asynchronous.
myRequestState = (RequestState)asynchronousResult.AsyncState;
HttpWebRequest myHttpWebRequest2 =
(HttpWebRequest)myRequestState.request;
// End of the Asynchronus writing .
Stream postStream =
myHttpWebRequest2.EndGetRequestStream(asynchronou sResult);
// send any post data
if(!Helpers.IsEmpty(myRequestState.m_strPostData))
{
ASCIIEncoding encoder = new ASCIIEncoding();
// Convert the string into byte array.
byte[] ByteArray = encoder.GetBytes(myRequestState.m_strPostData);
// Write to the stream.
postStream.Write(ByteArray,0,myRequestState.m_strP ostData.Length);
}
postStream.Close();
myRequestState.m_bResultOK = true;
m_allDone.Set();
}
catch(WebException e)
{
if(myRequestState != null)
{
myRequestState.m_strErrorText = e.Message;
myRequestState.m_bResultOK = false;
}
}
catch(Exception e)
{
if(myRequestState != null)
{
myRequestState.m_strErrorText = e.Message;
myRequestState.m_bResultOK = false;
}
}
m_allDone.Set();
}

// read response
private void RespCallback(IAsyncResult asynchronousResult)
{
RequestState myRequestState = null;
try
{
// State of request is asynchronous.
myRequestState = (RequestState) asynchronousResult.AsyncState;
HttpWebRequest myHttpWebRequest = myRequestState.request;
myRequestState.response = (HttpWebResponse)
myHttpWebRequest.EndGetResponse(asynchronousResul t);
// Read the response into a Stream object.
Stream responseStream =
myRequestState.response.GetResponseStream();
myRequestState.streamResponse = responseStream;
// Begin the Reading of the contents of the HTML page and print it
to the console.
IAsyncResult asynchronousInputRead =
responseStream.BeginRead(myRequestState.BufferRea d, 0, BUFFER_SIZE, new
AsyncCallback(ReadCallBack), myRequestState);
return;
}
catch(WebException e)
{
if(myRequestState != null)
{
myRequestState.m_bResultOK = false;
myRequestState.m_strErrorText = e.Message;
}
}
m_allDone.Set();
}

// read callback
private void ReadCallBack(IAsyncResult asyncResult)
{
RequestState myRequestState = null;
try
{
myRequestState = (RequestState)asyncResult.AsyncState;
Stream responseStream = myRequestState.streamResponse;
int read = responseStream.EndRead(asyncResult);
// Read the HTML page and then print it to the console.
if (read > 0)
{
myRequestState.m_strReply +=
Encoding.ASCII.GetString(myRequestState.BufferRea d, 0, read);
IAsyncResult asynchronousResult = responseStream.BeginRead(
myRequestState.BufferRead, 0, BUFFER_SIZE, new
AsyncCallback(ReadCallBack), myRequestState);
return;
}
else
{
myRequestState.m_bResultOK = true;
responseStream.Close();
}
}
catch(WebException e)
{
if(myRequestState != null)
{
myRequestState.m_bResultOK = false;
myRequestState.m_strErrorText = e.Message;
}
}
m_allDone.Set();
}

// Abort the request if the timer fires.
private void TimeoutSocketCallback(object state, bool timedOut)
{
if(timedOut)
{
HttpWebRequest request = state as HttpWebRequest;
if (request != null)
{
request.Abort();
}
}
}
}

// used for asyncronous requests
public class RequestState
{
// This class stores the State of the request.
const int BUFFER_SIZE = 1024;
public string m_strPostData;
public string m_strReply;
public string m_strErrorText;
public bool m_bResultOK;
public byte[] BufferRead;
public HttpWebRequest request;
public HttpWebResponse response;
public Stream streamResponse;
// constructor
public RequestState()
{
BufferRead = new byte[BUFFER_SIZE];
request = null;
streamResponse = null;
m_bResultOK = false;
m_strPostData = "";
m_strErrorText = "";
m_strReply = "";
}
}
}


Nov 19 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.