📄 webfunc.cs
字号:
using System;
using System.Net;
using System.Windows.Forms;
using feiyun0112.cnblogs.com.CSDNReader.Controls;
using feiyun0112.cnblogs.com.CSDNReader.Model;
using System.Collections.Generic;
using System.Threading;
using System.IO;
namespace feiyun0112.cnblogs.com.CSDNReader.Functions
{
/// <summary>
/// Summary description for WEBFunc.
/// </summary>
public class WEBFunc
{
private static volatile int _activeRequestCount = 0;
private static volatile int _maxConnections = 15;
private static bool blnNeedSort;
private static object _lockAddCookieobject = new object();
private static object _lockQueueobject = new object();
public static int MaxConnections
{
get
{
return _maxConnections;
}
set
{
bool increased = value > _maxConnections;
_maxConnections = value;
if (increased)
{
lock (_workQueue)
{
Monitor.Pulse(_workQueue);
}
}
}
}
private static List<RequestState> _workQueue = new List<RequestState>();
static WEBFunc()
{
Thread thread = new Thread(new ThreadStart(RequestThread));
thread.Priority = ThreadPriority.Normal;
thread.IsBackground = true;
thread.Start();
}
private static void RequestThread()
{
while (true)
{
try
{
RequestState rs = null;
lock (_workQueue)
{
while ((_workQueue.Count == 0) || (_activeRequestCount >= MaxConnections))
{
Monitor.Wait(_workQueue);
}
rs = Dequeue();
_activeRequestCount++;
}
try
{
if (!rs.FireStartDownload())
{
RequestException(rs, new Exception("Start"));
}
}
catch (Exception e)
{
}
try
{
IAsyncResult result = rs.requestInfo.Request.BeginGetResponse(new AsyncCallback(RespCallback), rs);
ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), rs, Setting.TimeoutMinutes, true);
}
catch (Exception e)
{
RequestException(rs, e);
}
}
catch (Exception e)
{
}
}
}
private static void RespCallback(IAsyncResult ar)
{
RequestState rs = (RequestState)ar.AsyncState;
try
{
HttpWebResponse resp = (HttpWebResponse)rs.requestInfo.Request.EndGetResponse(ar);
if ((resp.StatusCode != HttpStatusCode.OK) && (resp.StatusCode != HttpStatusCode.Accepted))
{
Retry(rs, new WebException("Server-response: " + resp.StatusCode, null, WebExceptionStatus.ConnectFailure, resp));
}
else
{
if (Variant.CurrentUser != null)
{
AddCookies(resp.Cookies);
}
rs.ContentEncoding = resp.ContentEncoding;
Stream responseStream = resp.GetResponseStream();
rs.ResponseStream = responseStream;
IAsyncResult result =responseStream.BeginRead(rs.BufferRead, 0, RequestState.BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs);
ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), rs, Setting.TimeoutMinutes, true);
}
}
catch (WebException e)
{
if (e.Status != WebExceptionStatus.RequestCanceled)
{
Retry(rs, e);
}
else
{
RequestException(rs, e);
}
}
catch (Exception e)
{
RequestException(rs, e);
}
}
public static void TimeoutCallback(object input, bool timedOut)
{
if (timedOut)
{
RequestState rs = (RequestState)input;
Retry(rs, new WebException("Request timeout", WebExceptionStatus.Timeout));
}
}
private static void AddCookies(CookieCollection newCookies)
{
lock (_lockAddCookieobject)
{
if (newCookies.Count == 0)
{
return;
}
CookieCollection tmpCookies = new CookieCollection();
CookieCollection oldCookies = Variant.CurrentUser.Cookies;
bool blnExist;
foreach (System.Net.Cookie newcookie in newCookies)
{
tmpCookies.Add(newcookie);
}
foreach (System.Net.Cookie oldcookie in oldCookies)
{
blnExist = false;
foreach (System.Net.Cookie newcookie in tmpCookies)
{
if (newcookie.Name.Equals(oldcookie.Name))
{
blnExist = true;
break;
}
}
if (!blnExist)
{
tmpCookies.Add(oldcookie);
}
}
Variant.CurrentUser.Cookies = tmpCookies;
}
}
private static void Retry(RequestState rs, WebException e)
{
try
{
bool retryRequest = false;
if (e.Status == WebExceptionStatus.KeepAliveFailure)
{
retryRequest = true;
}
if (retryRequest)
{
HttpWebRequest failedRequest = rs.requestInfo.Request;
string strUrl = failedRequest.RequestUri.ToString();
RequestEnd(rs);
rs.requestInfo.Reset();
lock (_workQueue)
{
Enqueue(rs);
if (_activeRequestCount < MaxConnections)
{
Monitor.Pulse(_workQueue);
}
}
}
else
{
RequestException(rs, e);
}
}
catch (Exception e2)
{
RequestException(rs, e2);
}
}
private static void ReadCallBack(IAsyncResult asyncResult)
{
RequestState rs = (RequestState)asyncResult.AsyncState;
try
{
Stream responseStream = rs.ResponseStream;
int read = responseStream.EndRead(asyncResult);
if (read > 0)
{
rs.RequestData.Write(rs.BufferRead, 0, read);
IAsyncResult result=responseStream.BeginRead(rs.BufferRead, 0, RequestState.BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs);
ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), rs, Setting.TimeoutMinutes, true);
}
else
{
RequestComplete(rs);
}
}
catch (Exception e)
{
RequestException(rs, e);
}
}
private static void RequestComplete(RequestState rs)
{
RequestEnd(rs);
try
{
rs.FireRequestComplete();
}
catch (Exception e)
{
}
finally
{
rs.Dispose();
rs = null;
}
}
private static void RequestException(RequestState rs, Exception e)
{
RequestEnd(rs);
try
{
rs.FireRequestException(e);
}
catch (Exception ex)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -