Webclient在下載請求時沒法設置請求超時時間和請求讀寫超時時間。WebClient在異步下載時遇到網絡不通等問題時沒有響應超時形成app掛起。 網絡
1.Webclient請求超時設置
重寫Webclient的GetWebRequest方法,爲HttpWebRequest添加請求超時及讀寫超時 app
protected
override
WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
request.Timeout = 1000 * Timeout;
request.ReadWriteTimeout = 1000 * Timeout;
return request;
}
2.WebClient在異步下載 異步
建立計時器監視響應狀況,過時則取消下載 ide
public
class
Calculagraph
{
/// <summary>
/// 時間到事件
/// </summary>
public event TimeoutCaller TimeOver;
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 開始時間
/// </summary>
private DateTime _startTime;
private TimeSpan _timeout = new TimeSpan(0, 0, 10);
private bool _hasStarted = false;
object _userdata;
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 計時器構造方法
/// </summary>
/// <param name="userdata">計時結束時回調的用戶數據</param>
public Calculagraph(object userdata)
{
TimeOver += new TimeoutCaller(OnTimeOver);
_userdata = userdata;
}
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 超時退出
/// </summary>
/// <param name="userdata"></param>
public virtual void OnTimeOver(object userdata)
{
Stop();
}
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 過時時間(秒)
/// </summary>
public int Timeout
{
get
{
return _timeout.Seconds;
}
set
{
if (value <= 0)
return;
_timeout = new TimeSpan(0, 0, value);
}
}
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 是否已經開始計時
/// </summary>
public bool HasStarted
{
get
{
return _hasStarted;
}
}
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 開始計時
/// </summary>
public void Start()
{
Reset();
_hasStarted = true;
Thread th = new Thread(WaitCall);
th.IsBackground = true;
th.Start();
}
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 重置
/// </summary>
public void Reset()
{
_startTime = DateTime.Now;
}
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 中止計時
/// </summary>
public void Stop()
{
_hasStarted = false;
}
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 檢查是否過時
/// </summary>
/// <returns></returns>
private bool checkTimeout()
{
return (DateTime.Now - _startTime).Seconds >= Timeout;
}
![](http://static.javashuo.com/static/loading.gif)
private void WaitCall()
{
try
{
//循環檢測是否過時
while (_hasStarted && !checkTimeout())
{
Thread.Sleep(1000);
}
if (TimeOver != null)
TimeOver(_userdata);
}
catch (Exception)
{
Stop();
}
}
}
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 過時時回調委託
/// </summary>
/// <param name="userdata"></param>
public
delegate
void
TimeoutCaller(
object
userdata);
public
class
CNNWebClient : WebClient
{
![](http://static.javashuo.com/static/loading.gif)
private Calculagraph _timer;
private int _timeOut = 10;
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 過時時間
/// </summary>
public int Timeout
{
get
{
return _timeOut;
}
set
{
if (value <= 0)
_timeOut = 10;
_timeOut = value;
}
}
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 重寫GetWebRequest,添加WebRequest對象超時時間
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
request.Timeout = 1000 * Timeout;
request.ReadWriteTimeout = 1000 * Timeout;
return request;
}
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 帶過時計時的下載
/// </summary>
public void DownloadFileAsyncWithTimeout(Uri address, string fileName, object userToken)
{
if (_timer == null)
{
_timer = new Calculagraph(this);
_timer.Timeout = Timeout;
_timer.TimeOver += new TimeoutCaller(_timer_TimeOver);
this.DownloadProgressChanged += new DownloadProgressChangedEventHandler(CNNWebClient_DownloadProgressChanged);
}
![](http://static.javashuo.com/static/loading.gif)
DownloadFileAsync(address, fileName, userToken);
_timer.Start();
}
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// WebClient下載過程事件,接收到數據時引起
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CNNWebClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
_timer.Reset();//重置計時器
}
![](http://static.javashuo.com/static/loading.gif)
/// <summary>
/// 計時器過時
/// </summary>
/// <param name="userdata"></param>
void _timer_TimeOver(object userdata)
{
this.CancelAsync();//取消下載
}
}