I know that static methods aren't always thread safe but if designed properly they are thread safe because internal variables are reinitialized every run...
Below is some code I found here but it looks thread safe because all resources are internalized within the method. Yet it still throws a null pointer sometimes when it tries to release resources (I've commented the line).
public static string XmlHttpRequest(string urlString, string xmlContent)
{
string response = null;
HttpWebRequest httpWebRequest = null;//Declare an HTTP-specific implementation of the WebRequest class.
HttpWebResponse httpWebResponse = null;//Declare an HTTP-specific implementation of the WebResponse class
//Creates an HttpWebRequest for the specified URL.
httpWebRequest = (HttpWebRequest)WebRequest.Create(urlString);
try
{
byte[] bytes;
bytes = System.Text.Encoding.ASCII.GetBytes(xmlContent);
//Set HttpWebRequest properties
httpWebRequest.Method = "POST";
httpWebRequest.ContentLength = bytes.Length;
httpWebRequest.ContentType = "text/xml; encoding='utf-8'";
using (Stream requestStream = httpWebRequest.GetRequestStream())
{
//Writes a sequence of bytes to the current stream
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();//Close stream
}
//Sends the HttpWebRequest, and waits for a response.
httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
if (httpWebResponse.StatusCode == HttpStatusCode.OK)
{
//Get response stream into StreamReader
using (Stream responseStream = httpWebResponse.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
response = reader.ReadToEnd();
}
}
httpWebResponse.Close();//Close HttpWebResponse
}
catch (WebException we){}
catch (Exception ex) { throw new Exception(ex.Message); }
finally
{
httpWebResponse.Close();
//Here is the null in the line above
httpWebResponse = null;
httpWebRequest = null;
}
return response;
}
So for some reason the line I commented in the code is throwing a null because the httpWebResponse is null. I assume it's something to do with threads using this method. It only happens SOMETIMES.
It has nothing to do with threads. You are likely getting an exception before httpWebResponse is assigned a value. Since you are swallowing any WebException it is entirely possible for httpWebResponse to be null without you knowing that an exception occurred.
Also your other exception handler is throwing a new vanilla exception with just the message included. You lose all other information such as the base exception type and stack trace. You could just rethrow the original exception but that's the same thing as not having another catch block at all.
I would:
remove both catch blocks (or at least the second on)
wrap the httpWebResponse in a using block (then it will be closed automatically if an exception is thrown).
check to see if httpWebResponse before calling Close on it. (note that if you wrap it in a using you don't have to close it, so you don't have to check if it is null)
Also, setting httpWebResponse and httpWebRequest to null is pointless as well since they will be eligible for garbage collection as soon as the method exits.
Related
i think i'm missing something about how HttpWebRequest works via streaming when uploading large files.
basicly, i found out that i receive timeout exception when sending large files to the server, so a post suggested to do it via Async and handle the timeout myself.
The thing is, that after debugging, i found out that "GetRequestStreamAsync" method, and writing to it does nothing at the server side, the server is called only when doing GetResponseAsync
so my question is:
- code marked as //1 - it writes the file to the request stream, but i don't see that the memory is increasing, or the server even getting any request - where does the streaming go to?
This is basicly my code:
HttpWebRequest request = RESTUtils.InitializeRequest(...);
request.AllowWriteStreamBuffering = false;
request.ContentLength = i_InputStream.Length;
request.Timeout = 5000;
using (Stream requestStream = request.GetRequestStreamWithTimeout())
{
if (requestStream != null) //1
{
// We will write the stream to the request
byte[] buffer = new byte[UPLOAD_FILE_BUFFER_SIZE];
int read = i_InputStream.Read(buffer, 0, buffer.Length);
while (read > 0)
{
requestStream.Write(buffer, 0, read);
read = i_InputStream.Read(buffer, 0, buffer.Length);
}
}
}
using (var response = request.GetResponseWithTimeout(-1))
{
using (var responseStream = response.GetResponseStream())
{
}
}
public static class WebRequestExtensions
{
public static Stream GetRequestStreamWithTimeout(
this WebRequest request,
int? millisecondsTimeout = null)
{
return AsyncToSyncWithTimeout(
request.BeginGetRequestStream,
request.EndGetRequestStream,
millisecondsTimeout ?? request.Timeout);
}
public static WebResponse GetResponseWithTimeout(
this HttpWebRequest request,
int? millisecondsTimeout = null)
{
return AsyncToSyncWithTimeout(
request.BeginGetResponse,
request.EndGetResponse,
millisecondsTimeout ?? request.Timeout);
}
private static T AsyncToSyncWithTimeout<T>(
Func<AsyncCallback, object, IAsyncResult> begin,
Func<IAsyncResult, T> end,
int millisecondsTimeout)
{
var iar = begin(null, null);
if (!iar.AsyncWaitHandle.WaitOne(millisecondsTimeout))
{
var ex = new TimeoutException();
throw new WebException(ex.Message, ex, WebExceptionStatus.Timeout, null);
}
return end(iar);
}
}
Thanks!
== Edit 9/9/15 ==
Something even weirder happens, i'm attaching breakpoint right after GetResponseAsync, then i see that the server receives the call.
after that, i'm closing the process of the client -> the server is uploading the file successfully.
this happens also if i do "Abort".
anyone knows why?
Instead of using the old-style begin/end async pattern, you should consider switching to async/await which would greatly simplify your code.
You would then set the Timeout property against the request to a large value to accommodate your waiting time; then instead of using the callback-based async code, you could just do:
var request = SomeMethodToCreateRequest();
request.Timeout = int.MaxValue; // (don't do this)
var response = await request.GetResponse();
The timeout should be respected internally, and you get to simplify your code.
Following this tutorial http://msdn.microsoft.com/en-us/library/hh221581.aspx I created an HttpWebRequest.
Producing this code for the Callback function:
private void ReadCallback(IAsyncResult result)
{
HttpWebRequest request = result.AsyncState as HttpWebRequest;
if (request != null)
{
try
{
WebResponse response = request.EndGetResponse(result);
using (StreamReader streamReader1 = new StreamReader(response.GetResponseStream()))
{
string resultString = streamReader1.ReadToEnd();
}
}
catch (WebException e)
{
return;
}
}
}
Now I got some data in the resultString, but I can't return it the normal way because of the call being async (as one can read here: AsyncCallBack - Does it have to be static / Does it have to return void?).
I can create global variables and safe the resultString global to access it from everywhere, but I don't think that this is the proper way to do something like this. The MSDN just writes the results to the console (http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest(v=vs.95).aspx), not really the thing I want to.
Is there a "best practice" or something for proceeding with results form async calls (for using them in other methods that are called later on?
This issue is really bizarre and has eluded my attempts at debugging. It only occurs when running the app on a Surface tablet. It does not occur on an Asus tablet or while running in Visual Studio. In a particular scenario where Airplane mode has been turned on, a WebException is thrown that I am absolutely unable to catch. I'm not even entirely certain what in my code is causing it to happen, because some of my logging is not happening after a certain point in the code for an unknown reason. I can only assume it's caused by an HttpWebRequest, because of the type of exception being thrown, which appears to be coming from an internal .NET component. Here is the only debugging information I'm able to obtain. It's from the Windows Event Viewer:
Application: <myappname.exe>
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Net.WebException
Stack:
at System.Net.ServicePoint.ConnectSocketCallback(System.IAsyncResult)
at System.Net.LazyAsyncResult.Complete(IntPtr)
at System.Net.ContextAwareResult.Complete(IntPtr)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object, IntPtr)
at System.Net.Sockets.Socket.ConnectCallback()
at System.Net.Sockets.Socket.RegisteredWaitCallback(System.Object, Boolean)
at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(System.Object, Boolean)
I really wish I had more debugging information to provide, but I've tried everything I can think of with tons of try/catch blocks everywhere and logging after most calls--some of which isn't be executed. Does anyone have any clue as to what could be causing this?
EDIT 1:
Based on traces the exception appears to be thrown somewhere in here. Virtually everything is wrapped in a try/catch block, so I can't see how the WebException could possibly be slipping through.
byte[] bytes = Encoding.UTF8.GetBytes(requestXml.ToString());
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.ContentType = "text/xml";
try
{
IAsyncResult requestResult = (IAsyncResult)request.BeginGetRequestStream((rAsyncResult) =>
{
using (Stream uploadStream = request.EndGetRequestStream(rAsyncResult))
{
try
{
uploadStream.Write(bytes, 0, bytes.Length);
uploadStream.Flush();
}
catch (Exception e)
{
// Exception handling
}
finally
{
uploadStream.Dispose();
}
}
IAsyncResult responseResult = (IAsyncResult)request.BeginGetResponse((resAsyncResult) =>
{
try
{
using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(resAsyncResult))
{
try
{
data = ProcessResponse(XmlReader.Create(response.GetResponseStream()));
}
catch (Exception e)
{
// Exception handling
}
finally
{
response.Dispose();
}
}
}
catch (WebException e)
{
// Exception handling
}
}, null);
}, null);
}
catch (Exception e)
{
// Exception handling
}
EDIT 2:
I still have not found an acceptable solution. I'm currently checking the connection type before-hand and not allowing the code to continue if it's not connected to WiFi, Mobile, or Ethernet, but that doesn't catch the condition where it's connected to a network that has no Internet connection. WinRT has no solution to check Internet connectivity, and even the method I'm using is unfriendly to work with (it just passes back a number--http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/d8e76732-19d3-47b3-840f-70d87c75ce9f).
Did you try handling the Application.UnhandledException?
Add the event handler to the event in the App class constructor:
public App()
{
// keep the rest of the constructor
this.UnhandledException += OnUnhandledException;
}
In the event handler you can log the exception and mark is handled to prevent the app from closing / crashing:
void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// log e.Exception details for investigation
e.Handled = true;
}
The issue is probably due to an unhandled exception thrown in your callback; chances are high that the callback is executed asynchronously in a thread different from the one that called the initial request.BeginGetRequestStream and this is why you aren't catching it in the outer try/catch block.
You should be able to overcome this problem by wrapping the entire content of the callback in a try/catch block, that is:
IAsyncResult requestResult = (IAsyncResult)request.BeginGetRequestStream((rAsyncResult) =>
{
try
{
using (Stream uploadStream = request.EndGetRequestStream(rAsyncResult))
{
try
{
uploadStream.Write(bytes, 0, bytes.Length);
uploadStream.Flush();
}
catch (Exception e)
{
// Exception handling
}
finally
{
uploadStream.Dispose();
}
}
IAsyncResult responseResult = (IAsyncResult)request.BeginGetResponse((resAsyncResult) =>
{
try
{
using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(resAsyncResult))
{
try
{
data = ProcessResponse(XmlReader.Create(response.GetResponseStream()));
}
catch (Exception e)
{
// Exception handling
}
finally
{
response.Dispose();
}
}
}
catch (WebException e)
{
// Exception handling
}
}, null);
}
catch (Exception ex)
{
// Handle the exception as you wish
}
}, null);
Like Efran Cobisi said EndGetRequestStream is probably the function throwing the exception. Also a using statement will dispose the an object even if there is an exception so no need of a try finally to dispose it.
But in any case you should be using the async methods, that will make the code a lot more readable and exception easier to catch. The equivalent of your code will be:
byte[] bytes = Encoding.UTF8.GetBytes(requestXml.ToString());
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.ContentType = "text/xml";
try
{
using (Stream uploadStream = await request.GetRequestStreamAsync())
{
await uploadStream.WriteAsync(bytes, 0, bytes.Length);
await uploadStream.FlushAsync();
}
using (HttpWebResponse response = (HttpWebResponse) await request.GetRequestStreamAsync())
{
data = ProcessResponse(XmlReader.Create(response.GetResponseStream()));
}
}
catch (Exception e)
{
// Exception
}
Following program will connect to the web and get html content of “msnbc.com” webpage and print out the result. If it takes longer than 2 seconds to get data from the webpage, I want my method to stop working and return. Can you please tell me how can I do this with an example?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
gethtml();
MessageBox.Show("End of program");
}
public void gethtml()
{
HttpWebRequest WebRequestObject = (HttpWebRequest)HttpWebRequest.Create("http://msnbc.com/");
WebResponse Response = WebRequestObject.GetResponse();
Stream WebStream = Response.GetResponseStream();
StreamReader Reader = new StreamReader(WebStream);
string webcontent = Reader.ReadToEnd();
MessageBox.Show(webcontent);
}
}
Two seconds is far too long to block the UI. You should only block the UI if you are planning on getting the result in, say fifty milliseconds or less.
Read this article on how to do a web request without blocking the UI:
http://www.developerfusion.com/code/4654/asynchronous-httpwebrequest/
Note that this will all be much easier in C# 5, which is in beta release at present. In C# 5 you can simply use the await operator to asynchronously await the result of the task. If you would like to see how this sort of thing will work in C# 5, see:
http://msdn.microsoft.com/en-us/async
Set the Timeout property of your WebRequest object. Documentation
MSDN Example:
// Create a new WebRequest Object to the mentioned URL.
WebRequest myWebRequest=WebRequest.Create("http://www.contoso.com");
Console.WriteLine("\nThe Timeout time of the request before setting is : {0} milliseconds",myWebRequest.Timeout);
// Set the 'Timeout' property in Milliseconds.
myWebRequest.Timeout=10000;
// This request will throw a WebException if it reaches the timeout limit before it is able to fetch the resource.
WebResponse myWebResponse=myWebRequest.GetResponse();
As stated above .Timeout
public void gethtml()
{
HttpWebRequest WebRequestObject = (HttpWebRequest)HttpWebRequest.Create("http://msnbc.com/");
WebRequestObject.Timeout = (System.Int32)TimeSpan.FromSeconds(2).TotalMilliseconds;
try
{
WebResponse Response = WebRequestObject.GetResponse();
Stream WebStream = Response.GetResponseStream();
StreamReader Reader = new StreamReader(WebStream);
string webcontent = Reader.ReadToEnd();
MessageBox.Show(webcontent);
}
catch (System.Net.WebException E)
{
MessageBox.Show("Fail");
}
}
You can use the TimeOut property on HttpWebRequest
Consider switching to asynchronous downloading of the content. You will stop blocking UI thread and will be able to handle multiple requests easily. You will be able to increase timeout significantly without impact on UI, and can decide upon receiving response if you still want to fetch data.
If I create a stream inside of the try block and an exception is raised does the stream automatically get disposed of? For example:
try
{
Stream stream = response.GetResponseStream();
//Error Occurs
stream.Close();
}
catch
{
//Handle Error
}
If this is not the way to do it can you please suggest an approach?
No, you need to use finally
Stream stream;
try
{
stream = response.GetResponseStream();
//Error Occurs
}
catch
{
//Handle Error
}
finally
{
if(stream != null)
stream.Close();
}
Or, wrap your Stream declaration/definition in a using statement, which calls Close() automatically:
try
{
using(Stream stream = response.GetResponseStream())
{
//Error happens
}
//stream.Dispose(), which calls stream.Close(), is called by compiler here
}
catch
{
//Handle Error
}
Note that my two examples are not exactly equivalent - in the first, the exception is handled before steam.Close() is called, in the second the exception is handled after.
The stream will not automatically close in this case.
If you wanted to ensure it closes in this context you'll want to use finally to ensure closure.
Alternatively I'd wrap the whole stream in a using.
using(Steam stream = response.GetResponseStream())
{
// Do your work here
}
No, use a using block. It calls Dispose automatically when block finishes, even if an error occurs.
eg.
using (Stream stream = response.GetResponseStream())
{
// do something with stream
}
It's the same as:
Stream stream = null;
try
{
stream = response.GetResponseStream();
// do something with stream
}
finally
{
if (stream != null)
stream.Dispose();
}
There are many examples on the net. A quick Google revealed the following already on stackoverflow: 'using' statement vs 'try finally'
using (Stream stream = response.GetResponseStream())
{
}
Dispose() is called on scope exit. This is the correct idiom for ensuring cleanup of IDisposable objects.
using(resource) statement will take care of calling dispose.
The answer is no. It's best to close all resources in a finally block if you have some exception handling logic around your code.
No, to always ensure disposal, regardless of exceptions, you use:
try
{
Stream stream = response.GetResponseStream();
//Error Occurs
}
catch
{
//Handle Error
}
finally
{
if(stream!=null)
stream.Close();
}
or simply:
using (Stream stream = response.GetResponseStream())
{
}
Stream implements IDisposable interface.
You can use using() statements where the class implements IDisposable.
This will automatically take care of closing and disposing the object without writing finally.
try
{
using (var stream = response.GetResponseStream())
{
//Error happens
}
}
catch
{
//Handle Error
}