Why is this HttpWebRequest class unreliable?

S

sfoxover

Hi,

Could someone please give me some suggestions on how to make this class
robust? I need to be able to handle around 20 simultaneous 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(asynchronousResult);
// 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_strPostData.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 = "";
}
}
}
 
A

Alvin Bruney [MVP - ASP.NET]

I'm not sure what you mean by unrealiable. Connections are limited to a max
of 2. This setting is configurable in the configuration file. Alternatively,
you can use threading approaches to fire simultaneous requests.

--
Regards,
Alvin Bruney - ASP.NET MVP

[Shameless Author Plug]
The Microsoft Office Web Components Black Book with .NET
Now available @ www.lulu.com/owc, Amazon.com etc
Hi,

Could someone please give me some suggestions on how to make this class
robust? I need to be able to handle around 20 simultaneous 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(asynchronousResult);
// 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_strPostData.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 = "";
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top