WebClient 没有销毁 导致 Unity 卡死

最近在跟进游戏的资源更新功能,为了测试超时重试,我把访问对象设置为 google,众所周知google并不是不能访问,而是受到了长城dns污染,所以在浏览器中访问的时候,会过很久才会返回错误信息,这样的用来测试很方便。


在Unity 中使用 WebClient 对 Google 进行请求,大概要一分钟才会返回错误信息。

但是这时候发现了问题,如果在等待错误返回的中途,关闭游戏,然后再次点击 Play 按钮播放游戏的话,Unity就卡死了。


测试代码如下

using UnityEngine;
using System.Collections;
using System.Net;
using System;

public class NewBehaviourScript : MonoBehaviour
{

    WebClient _webClient = null;
    Uri _uri = null;

    // Use this for initialization
    void Start()
    {
        StartCoroutine(Download());
    }

    void OnGUI()
    {
    }

    IEnumerator Download()
    {
        _uri = new Uri("http://www.google.com");

        Debug.Log("1");
        _webClient = new WebClient();
        _webClient.DownloadStringCompleted += DownLoadStringCompleted;
        _webClient.DownloadProgressChanged += DownLoadProgressChanged;
        _webClient.Disposed += Disposed;
        _webClient.DownloadStringAsync(_uri,"1");

        yield break;
    }


    void DownLoadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        Debug.Log("DownLoadProgressChanged /" + e.UserState + " /" + e.ProgressPercentage + " / " + e.BytesReceived + " /" + e.TotalBytesToReceive);
    }

    void DownLoadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        Debug.Log("DownLoadStringCompleted /"+e.UserState+" /" + e.Cancelled + " / " + e.Error+" /"+e.Result);
    }

    void Disposed(object sender, EventArgs e)
    {
        Debug.Log("Disposed " + e.ToString());
    }
}


在公司一直没有发现,昨天晚上在家里测试的时候……

发现关闭游戏,过一段时间后,居然在Cosoler 里面打印出了 访问错误的信息。

WebClient 没有销毁 导致 Unity 卡死_第1张图片

这时候才想起来,WebClient 是多线程的,如果我没有销毁它,它就在后台一直执行着。


于是猜测第二次Play 的时候,是不是被 WebClient 卡住了?

于是我一直等待……

果然等了差不多半分钟,游戏启动了……


而且,如果等错误信息在控制台打印出来之后,再去Play 游戏,是马上可以 Play 游戏的。


所以,这次Unity 卡住的问题就是因为 WebClient 没有被销毁 引起的。


解决方法就是添加销毁 WebClient 的代码:

    void OnDestroy()
    {
        _webClient.CancelAsync();
        _webClient.Dispose();
        _webClient = null;
    }


--------------------------------------


随后发现了其它问题。

当销毁WebClient 之后,再第二次 new WebClient,即使第二个WebClient 销毁了,Unity 仍然会卡死!

测试代码如下‘’

using UnityEngine;
using System.Collections;
using System.Net;
using System;

public class NewBehaviourScript : MonoBehaviour
{

    WebClient _webClient = null;
    Uri _uri = null;

    // Use this for initialization
    void Start()
    {
        
    }

    void OnGUI()
    {
        if (GUILayout.Button("Start"))
        {
            StartCoroutine(Download());
        }
        if (GUILayout.Button("Stop"))
        {
            StartCoroutine(Stop());
        }
    }

    IEnumerator Download()
    {
        _uri = new Uri("http://www.google.com");

        Debug.Log("1");
        _webClient = new WebClient();
        _webClient.DownloadStringCompleted += DownLoadStringCompleted;
        _webClient.DownloadProgressChanged += DownLoadProgressChanged;
        _webClient.Disposed += Disposed;
        _webClient.DownloadStringAsync(_uri, "1");

        yield return new WaitForSeconds(1.0f);
        _webClient.CancelAsync();
        yield return new WaitForSeconds(1.0f);
        _webClient.Dispose();
        yield return new WaitForSeconds(1.0f);
        _webClient = null;

        yield return new WaitForSeconds(1.0f);

        Debug.Log("2");
        _webClient = new WebClient();
        _webClient.DownloadStringCompleted += DownLoadStringCompleted;
        _webClient.DownloadProgressChanged += DownLoadProgressChanged;
        _webClient.Disposed += Disposed;
        _webClient.DownloadStringAsync(_uri, "2");

        yield break;
    }

    IEnumerator Stop()
    {
        yield return new WaitForSeconds(1.0f);
        _webClient.CancelAsync();
        yield return new WaitForSeconds(1.0f);
        _webClient.Dispose();
        yield return new WaitForSeconds(1.0f);
        _webClient = null;
    }

    void DownLoadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        Debug.Log("DownLoadProgressChanged /" + e.UserState + " /" + e.ProgressPercentage + " / " + e.BytesReceived + " /" + e.TotalBytesToReceive);
    }

    void DownLoadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        Debug.Log("DownLoadStringCompleted /" + e.UserState + " /" + e.Cancelled + " / " + e.Error + " /" + e.Result);
    }

    void Disposed(object sender, EventArgs e)
    {
        Debug.Log("Disposed " + e.ToString());
    }

}

目前只好保持一个 WebClient 。。。

你可能感兴趣的:(WebClient 没有销毁 导致 Unity 卡死)