3

I am using the WebClient.DownloadFileAsync() method, and wanted to know how can i pass a parameter to the WebClient.DownloadFileCompleted event (or any other event for that matter), and use it in the invoked method.

My code:

public class MyClass { string downloadPath = "some_path"; void DownloadFile() { int fileNameID = 10; WebClient webClient = new WebClient(); webClient.DownloadFileCompleted += DoSomethingOnFinish; Uri uri = new Uri(downloadPath + "\" + fileNameID ); webClient.DownloadFileAsync(uri,ApplicationSettings.GetBaseFilesPath +"\" + fileNameID); } void DoSomethingOnFinish(object sender, AsyncCompletedEventArgs e) { //How can i use fileNameID's value here? } } 

How can I pass a parameter to DoSomethingOnFinish()?

2
  • The only way I can think of right now is, that you can hold the file name in a global private field and access it in DoSomethingOnFinish Commented Aug 29, 2016 at 11:27
  • @ ChristophKn that was my original solution, but thought maybe there is something more elegant :) When dealing with several downloads this becomes messy Commented Aug 29, 2016 at 12:33

1 Answer 1

11

You can use webClient.QueryString.Add("FileName", YourFileNameID); to add extra information.

Then to access it in your DoSomethingOnFinish function,

use string myFileNameID = ((System.Net.WebClient)(sender)).QueryString["FileName"]; to receive the file name.

This is what the code should look like:

string downloadPath = "some_path"; void DownloadFile() { int fileNameID = 10; WebClient webClient = new WebClient(); webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DoSomethingOnFinish); webClient.QueryString.Add("fileName", fileNameID.ToString()); Uri uri = new Uri(downloadPath + "\\" + fileNameID); webClient.DownloadFileAsync(uri,ApplicationSettings.GetBaseFilesPath +"\\" + fileNameID); } void DoSomethingOnFinish(object sender, AsyncCompletedEventArgs e) { //How can i use fileNameID's value here? string myFileNameID = ((System.Net.WebClient)(sender)).QueryString["fileName"]; } 

Even if this should work, you should be using Unity's UnityWebRequest class. You probably haven't heard about it but this is what it should look like:

void DownloadFile(string url) { StartCoroutine(downloadFileCOR(url)); } IEnumerator downloadFileCOR(string url) { UnityWebRequest www = UnityWebRequest.Get(url); yield return www.Send(); if (www.isError) { Debug.Log(www.error); } else { Debug.Log("File Downloaded: " + www.downloadHandler.text); // Or retrieve results as binary data byte[] results = www.downloadHandler.data; } } 
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the quick response, will check your solution now. The goal was to implement downloads on a separate thread. Is UnityWebRequest something i can use outside the main thread?
First, I want you to understand that the code in your question is not using Thread. You are using Async which is different from Thread. Although, Async is easier to use than Thread. As for UnityWebRequest, you ca't use it in another Thread. You can't use Unity's API in another Thread. Although, both code in my answer are equivalent and they both use Async.
This is from MSDN: "The file is downloaded asynchronously using thread resources that are automatically allocated from the thread pool." Doesn't this mean this function internally uses a worker thread to download the file? @Programmer
Thanks, i will read up on the subject. Regarding my original question- is there any way i can pass a ref to an object with the sender object? Similar to the way you suggested with the int type?
webClient.QueryString.Add( keyName, value ); was just the magic I needed. Thank you
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.