Webclient在下载请求时无法设置请求超时时间和请求读写超时时间。WebClient在异步下载时遇到网络不通等问题时没有响应超时造成app挂起。
Webclient在下载请求时无法设置请求超时时间和请求读写超时时间。WebClient在异步下载时遇到网络不通等问题时没有响应超时造成app挂起。
1.Webclient请求超时设置
重写Webclient的GetWebRequest方法,为HttpWebRequest添加请求超时及读写超时
protected override WebRequest GetWebRequest(Uri address)

{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
request.Timeout = 1000 * Timeout;
request.ReadWriteTimeout = 1000 * Timeout;
return request;
}
2.WebClient在异步下载
创建计时器监视响应情况,过期则取消下载
public class Calculagraph

{

/**//// <summary>
/// 时间到事件
/// </summary>
public event TimeoutCaller TimeOver;


/**//// <summary>
/// 开始时间
/// </summary>
private DateTime _startTime;
private TimeSpan _timeout = new TimeSpan(0, 0, 10);
private bool _hasStarted = false;
object _userdata;


/**//// <summary>
/// 计时器构造方法
/// </summary>
/// <param name="userdata">计时结束时回调的用户数据</param>
public Calculagraph(object userdata)

{
TimeOver += new TimeoutCaller(OnTimeOver);
_userdata = userdata;
}


/**//// <summary>
/// 超时退出
/// </summary>
/// <param name="userdata"></param>
public virtual void OnTimeOver(object userdata)

{
Stop();
}


/**//// <summary>
/// 过期时间(秒)
/// </summary>
public int Timeout

{
get

{
return _timeout.Seconds;
}
set

{
if (value <= 0)
return;
_timeout = new TimeSpan(0, 0, value);
}
}


/**//// <summary>
/// 是否已经开始计时
/// </summary>
public bool HasStarted

{
get

{
return _hasStarted;
}
}


/**//// <summary>
/// 开始计时
/// </summary>
public void Start()

{
Reset();
_hasStarted = true;
Thread th = new Thread(WaitCall);
th.IsBackground = true;
th.Start();
}


/**//// <summary>
/// 重置
/// </summary>
public void Reset()

{
_startTime = DateTime.Now;
}


/**//// <summary>
/// 停止计时
/// </summary>
public void Stop()

{
_hasStarted = false;
}


/**//// <summary>
/// 检查是否过期
/// </summary>
/// <returns></returns>
private bool checkTimeout()

{
return (DateTime.Now - _startTime).Seconds >= Timeout;
}

private void WaitCall()

{
try

{
//循环检测是否过期
while (_hasStarted && !checkTimeout())

{
Thread.Sleep(1000);
}
if (TimeOver != null)
TimeOver(_userdata);
}
catch (Exception)

{
Stop();
}
}
}


/**//// <summary>
/// 过期时回调委托
/// </summary>
/// <param name="userdata"></param>
public delegate void TimeoutCaller(object userdata);
public class CNNWebClient : WebClient

{

private Calculagraph _timer;
private int _timeOut = 10;


/**//// <summary>
/// 过期时间
/// </summary>
public int Timeout

{
get

{
return _timeOut;
}
set

{
if (value <= 0)
_timeOut = 10;
_timeOut = value;
}
}


/**//// <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;
}


/**//// <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);
}

DownloadFileAsync(address, fileName, userToken);
_timer.Start();
}


/**//// <summary>
/// WebClient下载过程事件,接收到数据时引发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CNNWebClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)

{
_timer.Reset();//重置计时器
}


/**//// <summary>
/// 计时器过期
/// </summary>
/// <param name="userdata"></param>
void _timer_TimeOver(object userdata)

{
this.CancelAsync();//取消下载
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?