I'm using the following code in my program, would I still need to call response.close()? Or does the FtpWebResponse IDisposable implementation close the response?
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
}
So basically, would I need to do this?
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
response.close();
}
No you don't have to call Close, since Dispose already does that. FtpWebResponse is inherited from WebResponse and it has explicitly implemented Dispose, which internally call Close.
Code for WebResponse.cs from : http://www.dotnetframework.org/default.aspx/4#0/4#0/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/fx/src/Net/System/Net/WebResponse#cs/1305376/WebResponse#cs
/// <internalonly>
void IDisposable.Dispose() {
try
{
Close();
OnDispose();
}
catch { }
}
Related
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.
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?
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
}