0

I'm using WebClient.DownloadFileAsync while making youtube downloader and I have problem using it.

WebClient client = new WebClient();
Process.Text("", "Downloading video data...", "new");
client.DownloadFileAsync(new Uri(this.VidLink), this.path + "\\tempVid"); // Line3
Process.Text("", "Downloading audio data...", "old");
client.DownloadFileAsync(new Uri(this.AudLink), this.path + "\\tempAud"); // Line5

FFMpegConverter merge = new FFMpegConverter();
merge.Invoke(String.Format("-i \"{0}\\tempVid\" -i \"{1}\\tempAud\" -c copy \"{2}{3}\"", this.path, this.path, dir, filename)); // Line8
merge.Stop();
Process.Text("", "Video merging complete", "new");

Process is another class I'm using, and it works quite well, so never mind about it. But where I am having problem is after executing Line 3. Line 3 and 4 are executed very well, and Line 5 won't be executed. When I used DownloadFile instead of DownloadFileAsync, the code worked very well, so this.AudLink is no problem. Line 5 also works very well when I delete Line 3.

Similarly, When I delete Line 3 and Line 5 goes very well, Line 8 won't be executed. So what's the problem with this code? Should I kill the process used by client or something?

++) I'm not going to use youtube-dl during downloading video data, so please don't tell me to use youtube-dl instead.

Charlie Lee
  • 91
  • 1
  • 5
  • 1
    You should be `await`ing your async calls, or using some other method to determine when they're done. – Jamiec Sep 27 '17 at 10:04
  • @Jamiec I was wondering the same.. if the code snippet was incomplete or incorrect.. Alternatively all awaitable methods can call .Result but I wouldn't advise that. – rmjoia Sep 27 '17 at 10:05
  • await or try using 2 different objects of webClient, or do it in different tasks, and use Task1. ContinueWith with other one. – Amit Kumar Singh Sep 27 '17 at 10:06

1 Answers1

1

You should start off reading the best practices for async programming and note that one of the tenets is "async all the way".

Applied to your code, whatever method/class your code is inside of should itself be async. At that point, you can await your async downloads

private async Task DoMyDownloading()
{
  WebClient client = new WebClient();
  Process.Text("", "Downloading video data...", "new");
  await client.DownloadFileAsync(new Uri(this.VidLink), this.path + "\\tempVid"); // Line3
  Process.Text("", "Downloading audio data...", "old");
  await client.DownloadFileAsync(new Uri(this.AudLink), this.path + "\\tempAud"); // Line5

  FFMpegConverter merge = new FFMpegConverter();
  merge.Invoke(String.Format("-i \"{0}\\tempVid\" -i \"{1}\\tempAud\" -c copy \"{2}{3}\"", this.path, this.path, dir, filename)); // Line8
  merge.Stop();
  Process.Text("", "Video merging complete", "new");
}
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • I solved the problem by using to `client` objects and downloading audio data when `AsyncCompletedEvent` occurred. Thank you for the advice, though, and the document you offered me to read was very helpful. – Charlie Lee Sep 28 '17 at 04:35