WebClient 没有销毁 导致 Unity 卡死
2016-05-07 13:07
344 查看
最近在跟进游戏的资源更新功能,为了测试超时重试,我把访问对象设置为 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 是多线程的,如果我没有销毁它,它就在后台一直执行着。
于是猜测第二次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 。。。
在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 是多线程的,如果我没有销毁它,它就在后台一直执行着。
于是猜测第二次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 。。。
相关文章推荐
- Unity3D 场景平移、缩放
- 【翻译】 Unity3D VR 教程:3.VR中的交互
- Unity3d Update和FixedUpdate、LateUpdate的区别
- unity 控制移动的方法
- Unity3D 摄像机(Camera)
- Unity中Awake与Start函数的区别
- Unity 模仿官方例子 点击时添加爆炸力
- Unity3D之详解游戏开发音频的播放
- Unity3D脚本手册
- Unity3D用户手册
- Unity3D组件参考手册
- Unity Shaders and Effects Cookbook (6-3) 修改渲染队列Queue 来 修改渲染顺序
- Unity3d中脚本生命周期
- Unity 各个版本破解
- 【Unity开发】Unity中触摸和鼠标操作的几个问题
- Unity -- EventSystem完全掌握
- 使用Unity3d的Physics.Raycast()的用法做子弹射击
- Unity3D的场景单位 和 3D建模软件的单位 之间的关系
- unity3d发布一个Android的apk文件需要具备什么环境及具体操作步骤
- unity 游戏物体自动循环移动脚本