I'm developing a windows store app, and I'm uploading a file to an FTP server with WebRequest, since it was the only work around I could find, with the limitations that I had.
When the application is uploading the video, which takes a few minutes, if the user taps the screen the app will crash. If no input is made, it will work fine.
When I was using Alex Pilotti's FTPS Client DLL, this didn't happen, but I couldn't get the certification for windows store using this DLL.
In my PC, this doesn't happen. It will wait until the video is uploaded and then execute the user input, but in the tablet it's a different story, maybe because it has less processing power/memory, it just crashes.
I was thinking: maybe there is a way to ignore all user input while the upload is happening.
I know it's not the best way, to take control from the user like that, but it would do the job and it would only be for a few minutes.
I've been googling, but I can't find a way to do this.
I'll leave my code below, just in case:
Public Async Function uploadFile(filename As String, file As StorageFile) As Task(Of Boolean)
Try
Dim ftpURL As String = "ftp://111.22.33.444"
Dim request As WebRequest = WebRequest.Create(ftpURL + "/" + filename)
request.Credentials = New NetworkCredential("user", "pass")
request.Method = "STOR"
Dim buffer As Byte() = Await ReadFileToBinary(filename, file)
Dim requestStream As Stream = Await request.GetRequestStreamAsync()
Await requestStream.WriteAsync(buffer, 0, buffer.Length)
Await requestStream.FlushAsync()
Return True
Catch ex As Exception
Return False
End Try
End Function
I fixed this issue with a very simple line of code:
Await Task.Run(Function() uploadFile(filename, file))
Worked for me.
Related
I'm building a windows store application in VB.net, and when I try to get the certification, so I can publish it in the store, it fails the API test, because it doesn't accept the fact that I used AlexPilotti's FTPSClient dll.
The only thing I have to do is to upload a small video to the ftp server. Pretty simple, right? It's working properly, both in PC and Tablet, the only problem is the certification.
I had to use AlexPilotti's FTPSClient dll because "ftpwebrequest" is gone from Windows Store.
So, I wonder if there is anything else I can try, maybe a windows store compatible dll?
I have tried BackgroundTransfer, but apparently it only works with HTTP and HTTPS, not FTP.
I've been trying to find an answer for a few days now, but what I find never seems to work.
Thanks in advance!
Found this example by searching but didn't test it. Google is a programmers best friend.
Public Async Function FTP_Uploader(ftpURL As String, filename As String, username As String, password As String, UploadText As String) As Task(Of Boolean)
Try
Dim request As WebRequest = WebRequest.Create(ftpURL + "/" + filename)
request.Credentials = New System.Net.NetworkCredential(username.Trim(), password.Trim())
request.Method = "STOR"
Dim buffer As Byte() = Encoding.UTF8.GetBytes(UploadText)
Dim requestStream As Stream = Await request.GetRequestStreamAsync()
Await requestStream.WriteAsync(buffer, 0, buffer.Length)
Await requestStream.FlushAsync()
Return True
Catch ex As Exception
Return False
End Try End Function
I couldn't find a full example for PostAsync so I had to piece one together. Therefore, I am not sure if what I am viewing is a limitation with the debugger or I simply did it wrong.
This is what I am trying to do:
I have to go through a list and make a web service call for each item on the list. My thought is that I could use the new 4.5 async stuff to keep it flowing without blocking during each call to the web service.
I've done a tone of research and watched Jon Skeet's video on TekPub, but I'm still not sure if I am doing this correctly. That is, when I set break points my async method never returns control to the caller. It basically seems to go along exactly as my synchronous version.
Question:
Is it normal for the debugger to appear synchronous or does that indicate my code is not implemented correctly?
Here is my Post method:
Public Async Function PostSecureXMLAsync(ByVal username As String, ByVal password As String, ByVal XMLtoSend As String) As Task(Of String)
Dim content = New StringContent(XMLtoSend, Encoding.UTF8, "text/xml")
Dim credentials = New NetworkCredential(username, password)
Dim handler = New HttpClientHandler() With {.Credentials = credentials}
Using client = New HttpClient(handler)
Using response = client.PostAsync(APIurl, content).Result
Return Await response.Content.ReadAsStringAsync()
End Using
End Using
End Function
This is how it is being used:
For Each ListItem In ListObj
...
Result = XMLExchangeObj.PostSecureXMLAsync(Username, Password, Payload).Result
...
Next
I was expecting control to return to the For Each loop while it was waiting for replies from the Web Service, but based on my break points it seems to be running synchronously.
When you're working with Async, you don't want to call Wait or Result. Instead, you should use Await. I see one Result in PostSecureXMLAsync:
Using client = New HttpClient(handler)
Using response = Await client.PostAsync(APIurl, content) ' Changed to Await
Return Await response.Content.ReadAsStringAsync()
End Using
End Using
And there's another one when you call your Async method:
Result = Await XMLExchangeObj.PostSecureXMLAsync(Username, Password, Payload)
This does mean that your calling method must also be Async, which means any methods that call that method should use Await, and must also be Async, etc. This "growth" through your code is perfectly normal. Just allow Async to grow until you reach a natural stopping point (usually an event handler, which you can make Async Sub).
I am very new to vb/.net and I'm trying to do something that I can do easily in classic vb. I want to get the source html for a webpage from the URL.
I'm using vb.net in Visual Studio Express for Windows 8.
I've read loads of stuff that talk about HttpWebRequest, but I can't get it to work properly.
I did at one point have it returning the html header, but I want to content of the page. Now, I can't even get it back to giving me the header. Ultimately, I want to process the html returned which I'll do (to begin with) the old-fashioned way and process the returned html as a string, but for now I'd like to just get the page.
The code I've got is:
Dim URL As String = "http://www.crayola.com/"
Dim request As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create(New Uri(URL))
txtHTML.Text = request.GetRequestStreamAsync().ToString()
Can anyone help me with an example to get me going please?
You're trying to use an Async method in a synchronous way, which won't make any sense. If you're using .NET 4.5, you can try marking the calling method with Async and then using the Await keyword when calling GetRequestStreamAsync.
Public Sub MyDownloaderMethod()
Dim URL As String = "http://www.crayola.com/"
Dim request As System.Net.HttpWebRequest
= System.Net.HttpWebRequest.Create(New Uri(URL))
' Use the Await keyword wait for the async task to complete.
Dim response = request.GetResponseAsync()
txtHTML.Text = response.GetResponseStream().ToString()
End Function
See the following MSDN article for more information on async programming with the Await keyword: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx
Edit
You are receiving your error because you're trying to get the Request stream (what you send the server), and what you really want is the Response stream (what the server sends back to you). I've updated my code to get the WebResponse from your WebRequest and then retrieve the stream from that.
Public Shared Function GetWebPageString(ByVal address As Uri) As String
Using client As New Net.WebClient()
Return client.DownloadString(address)
End Using
End Function
There is also DownloadStringAsync if you don't want to block
request.GetRequestStreamAsync() is probably not a method. I think you're cribbing code from a site where someone wrote their own add-on methods to HttpWebRequest. Try request.GetResponse() to return a response object, then in the response object you can inspect the stream and convert it to text if you need to.
This worked for me in VB.Net 4.5
Public Async Sub GetHTML()
Dim PageHTML as string
Dim client As New HttpClient
Dim getStringTask As Task(Of String) = client.GetStringAsync(PageURL)
PageHTML = Await getStringTask
MsgBox(PageHTML)
End Sub
i wrote a function for download a webpage : function like:
public string GetWebPage(string sURL)
{
System.Net.WebResponse objResponse = null;
System.Net.WebRequest objRequest = null;
System.IO.StreamReader objStreamReader = null;
string sResultPage = null;
try
{
objRequest = System.Net.HttpWebRequest.Create(sURL);
objResponse = objRequest.GetResponse();
objStreamReader = new System.IO.StreamReader(objResponse.GetResponseStream());
sResultPage = objStreamReader.ReadToEnd();
return sResultPage;
}
catch (Exception ex)
{
return "";
}
}
But my problem is that. when this function working at that time application goto freeze (not response) and that time my can't not do any thing. How can i solve this problem. when downloading at time user can do other thing in my application.
Welcome to the world of blocking IO.
Consider the following:
You want your program to download a web page and then return the first 10 letters it finds in the source html. Your code might look like this:
...
string page = GetWebPage("http://example.com"); // download web page
page = page.Substring(0, 10);
Console.WriteLine(page);
....
When your program calls GetWebPage(), it must WAIT for the web page to be fully downloaded before it can possibly try to call Substring() - else it may try to get the substring before it actually downloads the letters.
Now consider your program. You've got lots of code - maybe a GUI interface running - and it's all executing line by line one instruction at a time. When your code calls GetWebPage(), it can't possibly continue executing additional code until that request is fully finished. Your entire program is waiting on that request to finish.
The problem can be solved in a few different ways, and the best solution depends on exactly what you're doing with your code. Ideally, your code needs to execute asynchronously. c# has methods that can handle a lot of this for you, but one way or another, you're going to want to start some work - downloading the web page in your case - and then continue executing code until your main thread is notified that the webpage is fully downloaded. Then your main thread can begin parsing the return value.
I'm assuming that since you've asked this question, you are very new to threads and concurrency in general. You have a lot of work to do. Here are some resources for you to read up about threading and implementing concurrency in c#:
C# Thread Introduction
.NET Asynchronous IO Design
the best was is to use thread
new Thread(download).Start(url);
and if your download page size is large use chunk logic.
HttpWebRequest ObjHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(Convert.ToString(url));
ObjHttpWebRequest.AddRange(99204);
ObjHttpWebRequest.Timeout = Timeout.Infinite;
ObjHttpWebRequest.Method = "get";
HttpWebResponse ObjHttpWebResponse = (HttpWebResponse)ObjHttpWebRequest.GetResponse();
Stream ObjStream = ObjHttpWebResponse.GetResponseStream();
StreamReader ObjStreamReader = new StreamReader(ObjStream);
byte[] buffer = new byte[1224];
int length = 0;
while ((length = ObjStream.Read(buffer, 0, buffer.Length)) > 0)
{
downloaddata += Encoding.GetEncoding(936).GetString(buffer);
To get around twitters streaming API not having a crossdomain file to access it from client side( in this case Silverlight) I have made a Generic Handler file in a web project which basically downloads the stream from twitter and as it reads it, writes it to the client.
Here is the handler code:
context.Response.Buffer = false;
context.Response.ContentType = "text/plain";
WebRequest request = WebRequest.Create("http://stream.twitter.com/1/statuses/filter.json?locations=-180,-90,180,90");
request.Credentials = new NetworkCredential("username", "password");
StreamReader responseStream = new StreamReader(request.GetResponse().GetResponseStream(), Encoding.GetEncoding("utf-8"));
while (!responseStream.EndOfStream)
{
string line = "(~!-/" + responseStream.ReadLine() + "~!-/)";
context.Response.BinaryWrite((Encoding.UTF8.GetBytes(line)));}
And this does work, but the problem is that once the client disconnects the handler just carry's on downloading. So how do I tell if the client is still busy receiving the request and if not, end the while loop?
Also, my second problem is that on the client side doing a "ReadLine()" does nothing, presumably because it is counting the entire stream as one line so never gets the full response. To work around that I read it byte by byte and when it sees "(~!-/" around something it know that is one line. VERY hacky, I know.
Thanks!
Found the answer!
while (context.Response.IsClientConnected)
:)