WebClient DownloadFileAsync() does not work with the same URl and Credentials...
Any clue?
static void Main(string[] args)
{
try
{
var urlAddress = "http://mywebsite.com/msexceldoc.xlsx";
using (var client = new WebClient())
{
client.Credentials = new NetworkCredential("UserName", "Password");
// It works fine.
client.DownloadFile(urlAddress, #"D:\1.xlsx");
}
/*using (var client = new WebClient())
{
client.Credentials = new NetworkCredential("UserName", "Password");
// It y creats file with 0 bytes. Dunow why is it.
client.DownloadFileAsync(new Uri(urlAddress), #"D:\1.xlsx");
//client.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
}*/
}
catch (Exception ex)
{
}
}
You need to keep the program running while the async download completes, as it runs in another thread.
Try something like this, and wait for it to say completed before you hit enter to end the program:
static void Main(string[] args)
{
try
{
var urlAddress = "http://mywebsite.com/msexceldoc.xlsx";
using (var client = new WebClient())
{
client.Credentials = new NetworkCredential("UserName", "Password");
client.DownloadFileAsync(new Uri(urlAddress), #"D:\1.xlsx");
client.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
}
catch (Exception ex)
{
}
Console.ReadLine();
}
public static void Completed(object o, AsyncCompletedEventArgs args)
{
Console.WriteLine("Completed");
}
Depending what kind of app you're using this in, the main thread needs to keep running while the background thread downloads the file.
By declaring Main function as async, you can also use DownloadFileTaskAsync with await.
public static async void Main(string[] args)
{
var urlAddress = "http://mywebsite.com/msexceldoc.xlsx";
var fileName = #"D:\1.xlsx";
using (var client = new WebClient())
{
await client.DownloadFileTaskAsync(new Uri(urlAddress), fileName);
}
}
Related
I'm trying to use WebClient.DownloadFileTaskAsync to download a file so that I can make use of the download progress event handlers. The problem is that even though I'm using await on DownloadFileTaskAsync, it's not actually waiting for the task to finish and exits instantly with a 0 byte file. What am I doing wrong?
internal static class Program
{
private static void Main()
{
Download("http://ovh.net/files/1Gb.dat", "test.out");
}
private async static void Download(string url, string filePath)
{
using (var webClient = new WebClient())
{
IWebProxy webProxy = WebRequest.DefaultWebProxy;
webProxy.Credentials = CredentialCache.DefaultCredentials;
webClient.Proxy = webProxy;
webClient.DownloadProgressChanged += (s, e) => Console.Write($"{e.ProgressPercentage}%");
webClient.DownloadFileCompleted += (s, e) => Console.WriteLine();
await webClient.DownloadFileTaskAsync(new Uri(url), filePath).ConfigureAwait(false);
}
}
}
As others have pointed, The two methods shown are either not asynchronous or not awaitable.
First, you need to make your download method awaitable:
private async static Task DownloadAsync(string url, string filePath)
{
using (var webClient = new WebClient())
{
IWebProxy webProxy = WebRequest.DefaultWebProxy;
webProxy.Credentials = CredentialCache.DefaultCredentials;
webClient.Proxy = webProxy;
webClient.DownloadProgressChanged += (s, e) => Console.Write($"{e.ProgressPercentage}%");
webClient.DownloadFileCompleted += (s, e) => Console.WriteLine();
await webClient.DownloadFileTaskAsync(new Uri(url), filePath).ConfigureAwait(false);
}
}
Then, you either wait on Main:
private static void Main()
{
DownloadAsync("http://ovh.net/files/1Gb.dat", "test.out").Wait();
}
Or, make it asynchronous, too:
private static async Task Main()
{
await DownloadAsync("http://ovh.net/files/1Gb.dat", "test.out");
}
I'm currently doing this:
static void Main(string[] args) {
string tempFile = Path.GetTempFileName();
Console.Write(tempFile);
var client = new RestClient(BaseURL);
using (var writer = File.OpenWrite(tempFile)) {
var req = new RestRequest {
ResponseWriter = (responseStream) => {
using (responseStream) {
responseStream.CopyTo(writer);
}
}
};
var response = client.DownloadData(req);
}
Console.ReadKey();
}
And, it saves data to the specified Temp file. However, when another event is supposed to be sent; the file isn't updated. This is understandable when I read the code; but I have no idea what else to do to make it listen and not just download it once and save it to a file once.
I'm new to unity, I need a simple script to send a XML file (don't need to read contents) from "StreamingAssets" folder to our FTP server root folder with ability to change |"FTP User Name" "FTP Password" "FTP Host Name" "FTP Port"|. I have been seen some example in unity forums and unity documentation but nothing helped me. if you know simple ways please guide me thanks.
I found this but it doesn't work.
using UnityEngine;
using System.Collections;
using System;
using System.Net;
using System.IO;
public class Uploader : MonoBehaviour
{
public string FTPHost = "ftp.byethost7.com";
public string FTPUserName = "b7_18750253";
public string FTPPassword = "**********";
public string FilePath;
public void UploadFile()
{
WebClient client = new System.Net.WebClient();
Uri uri = new Uri(FTPHost + new FileInfo(FilePath).Name);
Debug.Log (uri);
client.Credentials = new System.Net.NetworkCredential(FTPUserName, FTPPassword);
client.UploadFileAsync(uri, "STOR", FilePath);
}
void start()
{
FilePath = Application.dataPath+"/StreamingAssets/data.xml";
UploadFile ();
}
}
Change this:
Uri uri = new Uri(FTPHost + new FileInfo(FilePath).Name);
With this:
Uri uri = new Uri(FTPHost + "/" + new FileInfo(FilePath).Name);
The method OnFileUploadCompleted shows that the URI hasn't "/".
The Uri constructor seemingly joins the file name with the path name without format. (Works for me in Unity 2018.2.3f1). There are other ways to format a url, I just try point the error.
Worst English ever, I know... :D
You are simply not calling the UploadFile() function from anywhere. Because it is a public function, I assumed it is being called from another script, but since the Debug.Log (uri); code is not showing anything,it is likely that the function is not being called at-all. You must call it from somewhere for it to run.
For testing purposes, call it from the Start() function. Add the code below to your script.
void Start()
{
UploadFile();
}
Note that you must attach the Uploader script to a GameObject in your scene. That GameObject must be enabled in order for your Start() function to be called.
EDIT:
Even when you do this, you will get error that says:
The format of the URI could not be determined: blah blah blah
Your "ftp.byethost7.com"; link should be "ftp://byethost7.com";
Here is a complete FTP upload code in Unity.
using UnityEngine;
using System.Collections;
using System;
using System.Net;
using System.IO;
public class Uploader : MonoBehaviour
{
public string FTPHost = "ftp://byethost7.com";
public string FTPUserName = "b7_18750253";
public string FTPPassword = "xxx";
public string FilePath;
public void UploadFile()
{
FilePath = Application.dataPath + "/StreamingAssets/data.xml";
Debug.Log("Path: " + FilePath);
WebClient client = new System.Net.WebClient();
Uri uri = new Uri(FTPHost + new FileInfo(FilePath).Name);
client.UploadProgressChanged += new UploadProgressChangedEventHandler(OnFileUploadProgressChanged);
client.UploadFileCompleted += new UploadFileCompletedEventHandler(OnFileUploadCompleted);
client.Credentials = new System.Net.NetworkCredential(FTPUserName, FTPPassword);
client.UploadFileAsync(uri, "STOR", FilePath);
}
void OnFileUploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
{
Debug.Log("Uploading Progreess: " + e.ProgressPercentage);
}
void OnFileUploadCompleted(object sender, UploadFileCompletedEventArgs e)
{
Debug.Log("File Uploaded");
}
void Start()
{
UploadFile();
}
}
using System.IO;
public void UploadFile2()
{
FilePath = Application.dataPath + "/StreamingAssets/ARITMETICA3DAZ1.txt";
Debug.Log("Path: " + FilePath);
Uri uri = new Uri(FTPHost + "/" + new FileInfo(FilePath).Name);
FtpState state = new FtpState();
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential (FTPUserName,FTPPassword);
state.Request = request;
state.FileName = FilePath;
request.BeginGetRequestStream(
//new AsyncCallback (EndGetStreamCallback),
new AsyncCallback (EndGetStreamCallback),
state
);
public class FtpState
{
private ManualResetEvent wait;
private FtpWebRequest request;
private string fileName;
private Exception operationException = null;
string status;
public FtpState()
{
wait = new ManualResetEvent(false);
}
public ManualResetEvent OperationComplete
{
get {return wait;}
}
public FtpWebRequest Request
{
get {return request;}
set {request = value;}
}
public string FileName
{
get {return fileName;}
set {fileName = value;}
}
public Exception OperationException
{
get {return operationException;}
set {operationException = value;}
}
public string StatusDescription
{
get {return status;}
set {status = value;}
}
}
public class AsynchronousFtpUpLoader
{
// Command line arguments are two strings:
// 1. The url that is the name of the file being uploaded to the server.
// 2. The name of the file on the local machine.
//
public static void Main(string[] args)
{
// Create a Uri instance with the specified URI string.
// If the URI is not correctly formed, the Uri constructor
// will throw an exception.
ManualResetEvent waitObject;
Uri target = new Uri (args[0]);
string fileName = args[1];
FtpState state = new FtpState();
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(target);
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example uses anonymous logon.
// The request is anonymous by default; the credential does not have to be specified.
// The example specifies the credential only to
// control how actions are logged on the server.
request.Credentials = new NetworkCredential ("anonymous","janeDoe#contoso.com");
// Store the request in the object that we pass into the
// asynchronous operations.
state.Request = request;
state.FileName = fileName;
// Get the event to wait on.
waitObject = state.OperationComplete;
// Asynchronously get the stream for the file contents.
request.BeginGetRequestStream(
new AsyncCallback (EndGetStreamCallback),
state
);
// Block the current thread until all operations are complete.
waitObject.WaitOne();
// The operations either completed or threw an exception.
if (state.OperationException != null)
{
throw state.OperationException;
}
else
{
Console.WriteLine("The operation completed - {0}", state.StatusDescription);
}
}
private static void EndGetStreamCallback(IAsyncResult ar)
{
FtpState state = (FtpState) ar.AsyncState;
Stream requestStream = null;
// End the asynchronous call to get the request stream.
try
{
requestStream = state.Request.EndGetRequestStream(ar);
// Copy the file contents to the request stream.
const int bufferLength = 2048;
byte[] buffer = new byte[bufferLength];
int count = 0;
int readBytes = 0;
FileStream stream = File.OpenRead(state.FileName);
do
{
readBytes = stream.Read(buffer, 0, bufferLength);
requestStream.Write(buffer, 0, readBytes);
count += readBytes;
}
while (readBytes != 0);
Console.WriteLine ("Writing {0} bytes to the stream.", count);
// IMPORTANT: Close the request stream before sending the request.
requestStream.Close();
// Asynchronously get the response to the upload request.
state.Request.BeginGetResponse(
new AsyncCallback (EndGetResponseCallback),
state
);
}
// Return exceptions to the main application thread.
catch (Exception e)
{
Console.WriteLine("Could not get the request stream.");
state.OperationException = e;
state.OperationComplete.Set();
return;
}
}
// The EndGetResponseCallback method
// completes a call to BeginGetResponse.
private static void EndGetResponseCallback(IAsyncResult ar)
{
FtpState state = (FtpState) ar.AsyncState;
FtpWebResponse response = null;
try
{
response = (FtpWebResponse) state.Request.EndGetResponse(ar);
response.Close();
state.StatusDescription = response.StatusDescription;
// Signal the main application thread that
// the operation is complete.
state.OperationComplete.Set();
}
// Return exceptions to the main application thread.
catch (Exception e)
{
Console.WriteLine ("Error getting response.");
state.OperationException = e;
state.OperationComplete.Set();
}
}
}
}
I am having a hard time convert the below code which i have created in 4.0 to 4.5 using HttpClient.
According to my understand i guess if i create multiple web requests in the GUI thread itself without blocking the GUI if i got with asynchronous requeest.
how to convert the below code to Asynchronous using HttpClient in 4.5
// This is what called when button is clicked
Task t3 = new Task(SpawnTask);
t3.Start();
//if noofthreads are less 50 then GUI is woking fine.. if number increases then takes much time for repaint..
//where as other softwares are working without any problem even if the threads are more than 500!! in the same system
public void SpawnTask()
{
try
{
ParallelOptions po = new ParallelOptions();
po.CancellationToken = cts.Token;
po.MaxDegreeOfParallelism = noofthreads;
Parallel.ForEach(
urls,
po,
url => checkpl(url));
}
catch (Exception ex)
{
}
}
public void checkpl(string url)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Timeout = 60*1000;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string stext = "";
using (BufferedStream buffer = new BufferedStream(response.GetResponseStream()))
{
using (StreamReader reader = new StreamReader(buffer))
{
stext = reader.ReadToEnd();
}
}
response.Close();
if (stext .IndexOf("domainname.com") != -1)
{
tfound = tfound + 1;
string lext = "Total Found : "+tfound.ToString();
label3.BeginInvoke(new InvokeDelegate(UpdateLabel), ltext);
slist.Add(url);
textBox2.BeginInvoke(new InvokeDelegate4(UpdateText), "Working Url " + url);
}
}
catch (Exception ex)
{
}
}
Since you are using .NET 4.5 you can use the new async and await keywords. Here is what it might look like.
private async void YourButton_Click(object sender, EventArgs args)
{
YourButton.Enabled = false;
try
{
var tasks = new List<Task>();
foreach (string url in Urls)
{
tasks.Add(CheckAsync(url));
}
await TaskEx.WhenAll(tasks);
}
finally
{
YourButton.Enabled = true;
}
}
private async Task CheckAsync(string url)
{
bool found = await UrlResponseContainsAsync(url, "domainname.com");
if (found)
{
slist.Add(url);
label3.Text = "Total Found: " + slist.Count.ToString();
textbox2.Text = "Working Url " + url;
}
}
private async Task<bool> UrlResponseContainsAsync(string url, string find)
{
var request = WebRequest.Create(url);
request.Timeout = 60 * 1000;
using (WebResponse response = await request.GetResponseAsync())
{
using (var buffer = new BufferedStream(response.GetResponseStream()))
using (var reader = new StreamReader(buffer))
{
string text = reader.ReadToEnd();
return text.Contains(find);
}
}
}
I am getting a timeout error while starting my Windows service. I am tring to download an XML file from a remote system which causes a timeout during the service OnStart.
This is the method I am calling from OnStart:
public static StreamReader GetResponseStream()
{
try
{
EventLog.WriteEntry("Epo-Service_Retriver", "Trying ...",
EventLogEntryType.Information);
CookieContainer CC = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
Utils.GetWeeklyPublishedURL());
request.Proxy = null;
request.UseDefaultCredentials = true;
request.KeepAlive = true; //THIS DOES THE TRICK
request.ProtocolVersion = HttpVersion.Version10; // THIS DOES THE TRICK
request.CookieContainer = CC;
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
EventLog.WriteEntry("Epo-Service_Retriver", "Connected to Internet...",
EventLogEntryType.SuccessAudit);
return reader;
}
}
Is there any possibility to avoid this timeout?
You'll want to start a thread to do that work.
This is how I recall doing it in 1.1 (this is little more than pseudo code), something like this;
protected override void OnStart(string[] args)
{
Foo f = new Foo(args);
f.MethodThatNeverExits();
}
private void MethodThatNeverExits()
{
LongRunningInitialization();
while (true)
{
Thread.Sleep(pollingInterval);
DoSomeWork();
}
}
Would become;
private AutoResetEvent shutDownEvent;
private Thread thread;
protected override void OnStart(string[] args)
{
shutDownEvent = new AutoResetEvent(false);
Foo f = new Foo(args);
thread = new Thread(new ThreadStart(f.MethodThatNeverExits()));
thread.Start();
}
private void MethodThatNeverExits()
{
LongRunningInitialization();
while (!shutDownEvent.WaitOne(pollingInterval, false))
{
DoSomeWork();
}
}
protected override void OnStop()
{
shutDownEvent.Set();
thread.Join(timeToWait);
}