天天看點

Unity中使用C#的WebClient的DownloadFileAsync異步回調不執行

在開發時遇到了一個很奇怪的問題,使用WebClient來異步下載下傳遠端資源,并且使用了WebClient的兩個異步回調方法DownloadProgressChanged和DownloadFileCompleted。在Unity編輯器中,兩個異步回調方法可以正常執行,當打包後發現,兩個異步回調方法根本不會執行,比較神奇的是遠端檔案居然下載下傳了下來。

通過無數次踩坑,發現是.net版本影響的。見下圖:

Unity中使用C#的WebClient的DownloadFileAsync異步回調不執行

代碼如下:

void Start()
        {
            downloader = new Downloader(assetName, downloadUrl, savePath);
            downloadBtn.onClick.AddListener(DownlodClick);
        }

        private void DownlodClick()
        {
            downloader.DownloadFileAsync(progress => { }, status =>
            {
                var result = (Downloader.DownloadResult)status;
                Debug.Log("download status:" + result);
            });
        }

        private WebClient client;
        private Action<float> progressHandler;
        private Action<int> completedHandler;

        public Downloader(string fileName, string downloadUrl, string savePath)
        {
            this.savePath = savePath;
            this.fileName = fileName;
            this.downloadUrl = downloadUrl;
            uri = new Uri(downloadUrl);
        }

        /// <summary>
        /// 異步下載下傳bundle
        /// </summary>
        /// <param name="progressHandler">傳輸進度handler,傳回百分比進度值0-100</param>
        /// <param name="completedHandler">下載下傳完成handler,DownloadResult類型</param>
        public void DownloadFileAsync(Action<float> progressHandler, System.Action<int>     completedHandler)
        {
            cancelled = false;
            client = new WebClient();
            this.progressHandler = progressHandler;
            this.completedHandler = completedHandler;
            if (!Directory.Exists(savePath))
            {
                Directory.CreateDirectory(savePath);
            }
            Debug.Log("fileName:" + fileName);
            client.DownloadFileAsync(uri, Path.Combine(savePath, fileName));
            downloading = true;
            client.DownloadProgressChanged += DownloadProgressChanged;
            client.DownloadFileCompleted += DownloadFileCompleted;
        }
           

若使用.net3.5,是完全沒有問題的;若使用.net4.6,則存在回調方法不執行的情況。

最終踩坑發現,當使用.net4.6時,無法在Unity主線程中使用WebClient的異步回調方法,必需通過開啟子線程的方法來執行,修改DownloadFileAsync方法如下

public void DownloadFileAsync(Action<float> progressHandler, System.Action<int>     completedHandler)
        {
            cancelled = false;
            client = new WebClient();
            this.progressHandler = progressHandler;
            this.completedHandler = completedHandler;
            if (!Directory.Exists(savePath))
            {
                Directory.CreateDirectory(savePath);
            }
            Debug.Log("fileName:" + fileName);
            //開啟子線程執行下載下傳和回調方法
            Thread t = new Thread(()=>{
                client.DownloadFileAsync(uri, Path.Combine(savePath, fileName));
                downloading = true;
                client.DownloadProgressChanged += DownloadProgressChanged;
                client.DownloadFileCompleted += DownloadFileCompleted;
            });
            t.Start();
        }
           

最終将項目打包後,再測試,問題解決!!!