Webclient DownloadFileAsync is way slower than downloading same file from Browser - c#

So I wrote a program which downloads mp3 files from a website. They are about 17mb and if I download them using my browser, each file takes 2 seconds. However using webClient.DownloadFileAsync each file takes roughly 2 minutes. I don't know how I can fix this; I tried changing the webClient Proxy setting, but without any success.
This is my code
List<string> links = new List<string> { };
WebClient client = new WebClient();
client.Proxy = GlobalProxySelection.GetEmptyWebProxy();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadFileAsync(new Uri(links[counter - 1]), #"downloads\" + removeInvalid + #"\" + removeInvalid + " " + counter + ".mp3");
client.Dispose();
Any help would be greatly appreaciated :)

I know that its too late, but for me helped set proxy to:
webClient.Proxy = WebRequest.DefaultWebProxy;
Setting proxy to null also didnt helped for me

Related

C# Read file in ftp when this file start with dot "." (hidden Files) [duplicate]

This question already has answers here:
FtpWebRequest ListDirectory does not return hidden files
(2 answers)
Closed 2 years ago.
I need read file in ftp, but this file start with a "." (hidden Files), for exemple .teste.txt.
I tried read this file using this code:
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)WebRequest.Create("ftp://" + strFTP + ":" + strPorta + strDiretorio);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
reqFTP.Credentials = new NetworkCredential(strUser, strPass);
response = (FtpWebResponse)reqFTP.GetResponse();
reader = new StreamReader(response.GetResponseStream());
string line = reader.ReadLine();
in this case I put " -al" in the end ftp url, using this code:
var reqFTP = (FtpWebRequest)WebRequest.Create("ftp://" + strFTP + ":" + strPorta + strDiretorio + " -al");
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
reqFTP.Credentials = new NetworkCredential(strUser, strPass);
response = (FtpWebResponse)reqFTP.GetResponse();
reader = new StreamReader(response.GetResponseStream());
string line = reader.ReadLine();
Your problem may not be about the file containing a "." or not, by the looks of the code I bet the problem is the lack of a bar "/" between strPorta and strDiretorio.
You can also check if the concatenated string used to create the WebRequest has any kind of typo regarding special characters, if so, try to escape tehm with a "\" like when you use a new line in text "\n".
EDIT
After reading the comment It occurred me that you are in fact trying to list the so called hidden files. In UNIX based systems the "." before the filename is used to flag that file as hidden.
The problem here is that the Object that you are using to connect in the FTP does not have the ability to show/list hidden files as seem in this other thread:
FtpWebRequest ListDirectory does not return hidden files
I recommend that you use the solution proposed by the user Jothi Prakash Anandan and try other Libraries if you really need the hidden files.

WebClient using file (file in use error)

I'm new to WinForms/C#/VB.NET and all and am trying to put together a simple application which downloads an MP3 file and edits its ID3 tags. This is what I've come up with so far :
Uri link = new System.Uri("URL");
wc.DownloadFileAsync(link, #"C:/music.mp3");
handle.WaitOne();
var file = TagLib.File.Create(#"C:/music.mp3");
file.Tag.Title = "Title";
file.Save();
The top section downloads the file with a pre-defined WebClient, but when I try to open the file in the first line of the second half, I run into this error The process cannot access the file 'C:\music.mp3' because it is being used by another process. which I'm guessing is due to the WebClient.
Any ideas on how to fix this? Thanks.
If using WebClient.DownloadFileAsync you should subscribe to the DownloadFileCompleted event and perform the remainder of your processing from that event.
Quick and dirty:
WebClient wc = new WebClient();
wc.DownloadfileCompleted += completedHandler;
Uri link = new System.Uri("URL");
wc.DownloadFileAsync(link, #"C:/music.mp3");
//handle.WaitOne(); // dunno what this is doing in here.
function completedHandler(Object sender, AsyncCompletedEventArgs e) {
var file = TagLib.File.Create(#"C:/music.mp3");
file.Tag.Title = "Title";
file.Save();
}

Text Encoding comes out corrupted after downloading from FTP

So i am making a program in c# with .net that uploads text files...
but everytime i upload a text file then download it on filezilla it comes out in chinese looking text..See here. im not sure if its because of encoding but if it helps heres my ftp code:
string ftpUsername = "#######";
string ftpPassword = "##########";
string localFilePath = path+ #"\" +FileName;
using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
client.UploadFile("ftp://###########/Logs/Text.txt", "STOR", localFilePath);
File.Delete(path + #"\" + FileName);
}
The reason the text file was coming out corrupted was not the upload method but the download method in FileZilla...
When you download you need to set the transfer type too binary...
this gets rid of the issue..

Wait until file is downloaded from URL via webClient

I have struggle with downloading few MB excel file from URL and then work with it. Im using VS2010 so i cant use await keyword.
My code follows:
using (WebClient webClient = new WebClient())
{
// setting Windows Authentication
webClient.UseDefaultCredentials = true;
// event fired ExcelToCsv after file is downloaded
webClient.DownloadFileCompleted += (sender, e) => ExcelToCsv(fileName);
// start download
webClient.DownloadFileAsync(new Uri("http://serverx/something/Export.ashx"), exportPath);
}
The line in ExcelToCsv() method
using (FileStream stream = new FileStream(filePath, FileMode.Open))
Throws me an error:
System.IO.IOException: The process cannot access the file because it
is being used by another process.
I tried webClient.DownloadFile() only without an event but it throws same error. Same error is throwed if i do not dispose too. What can i do ?
Temporary workaround may be Sleep() method but its not bullet proof.
Thank you
EDIT:
I tried second approach with standard handling but i have mistake in the code
using (WebClient webClient = new WebClient())
{
// nastaveni ze webClient ma pouzit Windows Authentication
webClient.UseDefaultCredentials = true;
// <--- I HAVE CONVERT ASYNC ERROR IN THIS LINE
webClient.DownloadFileCompleted += new DownloadDataCompletedEventHandler(HandleDownloadDataCompleted);
// spusteni stahovani
webClient.DownloadFile(new Uri("http://czprga2001/Logio_ZelenyKyblik/Export.ashx"), TempDirectory + PSFileName);
}
public delegate void DownloadDataCompletedEventHandler(string fileName);
public event DownloadDataCompletedEventHandler DownloadDataCompleted;
static void HandleDownloadDataCompleted(string fileName)
{
ExcelToCsv(fileName);
}
EDIT: approach 3
I tried this code
while (true)
{
if (isFileLocked(downloadedFile))
{
System.Threading.Thread.Sleep(5000); //wait 5s
ExcelToCsv(fileName);
break;
}
}
and it seems that it is never accessible :/ I dont get it.
Try to use DownloadFile instead of DownloadFileAsync, as you do in Edit 1, like this:
string filename=Path.Combine(TempDirectory, PSFileName);
using (WebClient webClient = new WebClient())
{
// nastaveni ze webClient ma pouzit Windows Authentication
webClient.UseDefaultCredentials = true;
// spusteni stahovani
webClient.DownloadFile(new Uri("http://czprga2001/Logio_ZelenyKyblik/Export.ashx"), filename);
}
ExcelToCsv(filename); //No need to create the event handler if it is not async
From your example it seems that you do not need asynchronous download, so use synchronous download and avoid possible related problems like here.
Also use Path.Combine to combine parts of a path like folder and filename.
There is also a chance that it is locked by something else, use Sysinternals Process Explorer's Find DLL or Handle function to check it.
Use local disk to store downloaded file to prevent problems with network.

WebClient.DownloadFileAsync - Download files one at a time

I am using the code below to download multiple attachments from a TFS server:
foreach (Attachment a in wi.Attachments)
{
WebClient wc = new WebClient();
wc.Credentials = (ICredentials)netCred;
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
wc.DownloadFileAsync(a.Uri, "C:\\" + a.Name);
}
I would like to download multiple files using DownloadFileAsync, but I want them to be downloaded one by one.
One may ask "Why don't you just use the synchronous DownloadFile method?" Its because:
I want to make use of the events provided by DownloadFileAsync.
I don't want to make multiple instances of the Webclient to avoid flooding the server.
This is the solution that I thought of:
foreach (Attachment a in wi.Attachments)
{
WebClient wc = new WebClient();
wc.Credentials = (ICredentials)netCred;
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
wc.DownloadFileAsync(a.Uri, "C:\\" + a.Name);
while (wc.IsBusy)
{
System.Threading.Thread.Sleep(1000);
}
}
However, there are a couple of problems with this approach:
The Thread.Sleep() is locking up my Form. I still need to make my own Thread or use BackgroundWorker. (I would like to avoid this as much as possible)
The DownloadFileCompleted event is being triggered after ALL files has been downloaded. I don't know if this is a side-effect of using System.Threading.Thread.Sleep(1000);
Is there a better approach to download files one at a time using WebClient.DownloadFileAsync?
Thanks!
To simplify the task you can create separated attachment list:
list = new List<Attachment>(wi.Attachments);
where list is private field with type List<Attachment>.
After this you should configure WebClient and start downloading of first file:
if (list.Count > 0) {
WebClient wc = new WebClient();
wc.Credentials = (ICredentials)netCred;
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
wc.DownloadFileAsync(list[0].Uri, #"C:\" + list[0].Name);
}
Your DownloadFileComplete handler should check if not all files already downloaded and call DownloadFileAsync again:
void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) {
// ... do something useful
list.RemoveAt(0);
if (list.Count > 0)
wc.DownloadFileAsync(list[0].Uri, #"C:\" + list[0].Name);
}
This code is not optimized solution. This is just idea.
At the risk of sounding like an idiot, this worked for me:
Console.WriteLine("Downloading...");
client.DownloadFileAsync(new Uri(file.Value), filePath);
while (client.IsBusy)
{
// run some stuff like checking download progress etc
}
Console.WriteLine("Done. {0}", filePath);
Where client is an instance of a WebClient object.
I think that should use Queue

Categories