DownloadFile works, DownloadFileAsync gets 0 bytes file - c#

I'm trying to download git from this url
https://github.com/msysgit/msysgit/releases/download/Git-1.9.5-preview20150319/Git-1.9.5-preview20150319.exe
I did it using DownloadFile, it worked OK.
Now I try to do it with Async method, but it downloads 0 byte file. Here's the code:
public void downloadFile(string urlAddress, string location)
{
using (var downloadClient = new WebClient())
{
downloadClient.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(Completed);
downloadClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
Uri URL = urlAddress.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ? new Uri(urlAddress) : new Uri("http://" + urlAddress);
_downloadStopWatch.Start();
try
{
downloadClient.DownloadFileAsync(URL, location);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
_downloadStopWatch.Stop();
while (downloadClient.IsBusy) { }
}
}
where:
private string _location = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\test.exe";
And urlAddress is typed into textbox and passed textbox.text
I check the Completed handler and it says completed.
Why am I getting 0 byte file?

The completed methods parameter AsyncCompletedEventArgs returns an error The remote name could not be resolved: 'https'.
In that case you should fall back to http
Depending on your target framework you could also use await downloadClient.DownloadFileTaskAsync(urlAddress, location);

Related

How i can set delay method to my upload function C#

I am using upload function in my desktop application. i want if upload function become unsuccessful then this method retry to upload it. Currently when upload is unsuccessful then it be me error of unhandled exception .i need solution of this
**This is function**
async Task Uploaded()
{
using (var dbx = new DropboxClient(token))
{
bmp = new Bitmap(picboxcapture.Image);
string folder = "/folder/"+Login.recuser+"";
string filename = DateTime.Now.ToString() + " " + " " + MyTodo_Project.rectsk + ".JPG";
string URL = picboxcapture.Image.ToString();
ImageConverter converter = new ImageConverter();
MemoryStream(File.ReadAllBytes(#"C:\Users\home\Downloads\FazalNEwTEst.JPG"));
byte[] bytes = (byte[])converter.ConvertTo(picboxcapture.Image, typeof(byte[]));
var mem = new MemoryStream(bytes);
var updated = dbx.Files.UploadAsync(folder + "/" + filename,
WriteMode.Overwrite.Instance, body: mem);
updated.Wait();
var tx = dbx.Sharing.CreateSharedLinkWithSettingsAsync(folder + "/" + filename);
tx.Wait();
URL = tx.Result.Url;
}
}
**The function call**
private async void save_Load(object sender, EventArgs e)
{
await Uploaded();
}
I want that when upload unsuccessful then it will retry to upload it in page load event . how can
i do this in C#
Just write your own retry handler. Or use Polly (recommended, as it's a mature and very successful library).
However, this is an example of how you might build your own.
Given
public class RetriesExceededException : Exception
{
public RetriesExceededException() { }
public RetriesExceededException(string message) : base(message) { }
public RetriesExceededException(string message, Exception innerException) : base(message, innerException) { }
}
public static async Task RetryOnExceptionAsync(int retryCount, int msDelay, Func<Task> func)
{
for (var i = 0; i < retryCount; i++)
{
try
{
await func.Invoke();
return;
}
catch (OperationCanceledException)
{
throw;
}
catch (Exception ex)
{
if (i == retryCount - 1)
throw new RetriesExceededException($"{retryCount} retries failed", ex);
}
await Task.Delay(msDelay)
.ConfigureAwait(false);
}
}
Usage
await RetryOnExceptionAsync(3, 1000, Uploaded);

Downloading a file from AWS S3 in Xamarin iOS Hangs mostly

I am trying to download an XML file of size 85MB in my Xamarin iOS iPad App.
Sometimes download completes successfully, but other times download hangs inbetween somewhere without giving any error. Progress stops.
AWS SDK version:
AWSSDK.S3 3.3.20.4
AWSSDK.Core 3.3.24.8
I tried both methods 1- TransferUtility 2- GetObject.
Here is my code:
var clientRequest = new AmazonS3Client(AWSAccessKey,
AWSSecretKey,
Amazon.RegionEndpoint.USEast1);
try
{
GetObjectRequest request = new GetObjectRequest
{
BucketName = AWSBucketName,
Key = Path + "File1.xml"
};
using (GetObjectResponse response = await clientRequest.GetObjectAsync(request))
{
response.WriteObjectProgressEvent += displayDownloadProgress;
await response.WriteResponseStreamToFileAsync(destPath, false);
}
}
catch (AmazonS3Exception e)
{
Console.WriteLine("Error encountered ***. Message:'{0}' when writing an object", e.Message);
}
catch (Exception e)
{
Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
}
I tried both methods one by one.
var utility = new TransferUtility(cas.AWSAccessKey,
cas.AWSSecretKey,
Amazon.RegionEndpoint.USEast1);
TransferUtilityDownloadRequest dr = new TransferUtilityDownloadRequest();
dr.BucketName = AWSBucketName;
dr.Key = Path + "File1.xml";
dr.FilePath = destPath;
dr.WriteObjectProgressEvent += displayDownloadProgress;
await utility.DownloadAsync(dr);
public void displayDownloadProgress(object sender, WriteObjectProgressArgs args)
{
Debug.WriteLine("Download Progress: " + (args.PercentDone));
InvokeOnMainThread(() =>
{
BTProgressHUD.ShowContinuousProgress("Download Progress: " + args.PercentDone.ToString() + "%", ProgressHUD.MaskType.Gradient);
});
if (args.PercentDone >= 100)
{
BTProgressHUD.Dismiss();
}
}

C# WebClient Downloads empty file

I'm working on an app that uses Bing's API to search and download images.
Bing's API provides a set of image links and I iterate over them and download each one.
The problem that I'm having is that sometimes the downloaded file size is 0Kb.
I assume that happens because WebClient first creates the filename and then tries to write to it. So when it can't write to it for some reason this happens. The problem is that it happens without throwing an exception so my 'Catch' statement can't catch this and delete the file.
public void imageFetcher(string performerName, int maxNumberOfImages, RichTextBox richTextBox)
{
string performersDirPath = Environment.CurrentDirectory + #"\Performers\";
string performerPath = performersDirPath + performerName + #"\";
if (!Directory.Exists(performersDirPath))
{
Directory.CreateDirectory(performersDirPath);
}
if (!Directory.Exists(performerPath))
{
Directory.CreateDirectory(performerPath);
}
// Searching for Images using bing api
IEnumerable<Bing.ImageResult> bingSearch = bingImageSearch(performerName);
int i = 0;
foreach (var result in bingSearch)
{
downloadImage(result.MediaUrl, performerPath + performerName + i + ".jpg",richTextBox);
i++;
if (i == maxNumberOfImages)
{
break;
}
}
}
The download method:
public void downloadImage(string imgUrl, string saveDestination, RichTextBox richTextBox)
{
if (File.Exists(saveDestination))
{
richTextBox.ForeColor = System.Drawing.Color.Red;
richTextBox.AppendText("The File: " + saveDestination + "Already exists");
}
else
{
try
{
using (WebClient client = new WebClient())
{
client.DownloadFileCompleted += new AsyncCompletedEventHandler(((sender, e) => downloadFinished(sender, e, saveDestination , richTextBox)));
Uri imgURI = new Uri(imgUrl, UriKind.Absolute);
client.DownloadFileAsync(imgURI, saveDestination);
}
}
catch (Exception e)
{
richTextBox.AppendText("There was an exception downloading the file" + imgUrl);
richTextBox.AppendText("Deleteing" + saveDestination);
File.Delete(saveDestination);
richTextBox.AppendText("File deleted!");
}
}
}
This happens also when I try to wait for the client to finish using:
client.DownloadFileAsync(imgURI, saveDestination);
while (client.IsBusy)
{
}
Can anyone please tell me what I'm doing wrong?
In other simular question the solution was to keep the Webclient instance open until download is finished.. I'm doing this with this loop:
while (client.IsBusy){}
Yet the results are the same.
Update:
I resorted to not use webclient, instead I used this code:
try
{
byte[] lnBuffer;
byte[] lnFile;
using (BinaryReader lxBR = new BinaryReader(stream))
{
using (MemoryStream lxMS = new MemoryStream())
{
lnBuffer = lxBR.ReadBytes(1024);
while (lnBuffer.Length > 0)
{
lxMS.Write(lnBuffer, 0, lnBuffer.Length);
lnBuffer = lxBR.ReadBytes(1024);
}
lnFile = new byte[(int)lxMS.Length];
lxMS.Position = 0;
lxMS.Read(lnFile, 0, lnFile.Length);
}
using (System.IO.FileStream lxFS = new FileStream(saveDestination, FileMode.Create))
{
lxFS.Write(lnFile, 0, lnFile.Length);
}
This solves the problem almost complelty, there are still one or two 0KB files but I assume it's because of network errors.
To see possible exceptions - try changing DownloadFileAsync to just DownloadFile - my problem was "Can not create SSL/TLS secure channel". Hope this will help someone.

C# WebApi sending a request from Global.asax resulting in a 404

I have a situation where I'm attempting to keep my web api application alive by sending a request to an MVC controller in the Api. I am getting the url in the Application_BeginRequest method in the Global.asax, then basically disassembling the URL and constructing it to hit a known controller method (route). When I get the url that it constructs and paste it in a browser the url works fine and returns the expected result. However when I user the same url in the application I get a 404 error.
Global.asax method that gets the URL from the first request:
void Application_BeginRequest(Object source, EventArgs e)
{
if (!initialized)
{
var rawurl = HttpContext.Current.Request.Url.AbsoluteUri;
capturedRequest = HttpContext.Current.Request;
if (!String.IsNullOrEmpty(rawurl))
{
if(!rawurl.ToLower().Contains("api"))
{
return;
}
lock (locked)
{
var urlparts = rawurl.Split('/');
if (urlparts.Length > 0)
{
siteUrl = "http://";
for (int i = 1; i < urlparts.Length - 1; i++)
{
if (!String.IsNullOrEmpty(urlparts[i]))
{
siteUrl += urlparts[i] + "/";
}
}
if (urlparts[urlparts.Length - 1].ToLower().Contains("api"))
{
siteUrl += urlparts[urlparts.Length - 1];
}
if(siteUrl[siteUrl.Length -1] != '/')
{
siteUrl += "/";
}
siteUrl += "Labels/GetAllDeploymentLabels";
initialized = true;
}
}
}
}
}
This gets the correct URL. I have a timer which every five minutes calls this method, also in the Global.asax method: (it returns a 404 error in the message.
private async void MakeKeepAliveRequest()
{
Repository repository = new Repository();
if (!String.IsNullOrEmpty(WebApiApplication.siteUrl))
{
try
{
HttpClient client = new HttpClient();
HttpResponseMessage message = await client.GetAsync(new Uri(WebApiApplication.siteUrl));
repository.WriteToApplicationLog("Keep Alive", null, Environment.MachineName + " : " + WebApiApplication.siteUrl + ": Global ASAX Keep Alive REQUEST SUCCEEDED: " + message + DateTime.Now, Core.ApplicationMessageType.Message);
}
catch (Exception ex)
{
repository.WriteToApplicationLog("Keep Alive", null, Environment.MachineName + ": Global ASAX Keep Alive REQUEST FAILED: " + ex.Message + " ::: " + DateTime.Now, Core.ApplicationMessageType.Message);
}
}
}
What am I missing, why can't it find the url from code, but works fine from the browser?

WebClient.DownloadFileTaskAsync and File.Exists

I'm using the following code to download a file and verify if the download succeeded:
try
{
UpdateAvailable = false;
Downloading = true;
using (var webclient = new WebClient { CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore) })
{
var file = Path.Combine(basePath, filename);
await webclient.DownloadFileTaskAsync(updaterexe_fileurl, Path.Combine(basePath, updaterexe_filename));
await webclient.DownloadFileTaskAsync(updatefileurl, file);
}
if (!File.Exists(filename))
{
Error = "Error downloading update. Please try again.";
Log.Error("Error downloading update. Please try again (file does not exist).");
}
else
{
DownloadReady = true;
}
}
catch (Exception ex)
{
Log.Error("Error downloading update: " + ex);
Error = ex.Message;
}
finally
{
Downloading = false;
}
This works in most cases. But I got multiple reports from end-users that sometimes they get the 'try again' error message.
How is this even possible? Clearly, WebClient didn't throw an exception, but it also failed to download the file (it did not exist on disk).
Is this a caching issue? Am I missing any other error handling?
If it's a disk caching issue, I thought about adding the following:
int count = 0;
while (count < 3 || !File.Exists(filename))
{
Thread.Sleep(1000);
count++;
}
But this feels very hacky.
Any ideas?
You download to file, which is Path.Combine(basePath, filename) but you never check to see whether file exists, you check to see whether filename exists.
If basePath and the current working directory differ, the file "won't exist".

Categories

Resources