public class SyncDownloader
{
public delegate byte[] DownloadBytesHandle(string pFileName, long pPosition, int pMaxSize);
System.IO.FileStream write = null;
long pos = 0;
int lastReceiveSize = 0;
int bufferVersion = 0;
SyncDownloadItem curDown;
public SyncDownloader()
{
}
private ManualResetEvent timeoutObject = new ManualResetEvent(false);
public bool StartDownload(string fileName, string localFullPath)
{
int buffersize = 50000;//默认500K一次 25000 12500 6000 3000 1500
bufferVersion = 0;
pos = 0;
lastReceiveSize = buffersize;//默认与最大的一致
bool isOk = false;
int timeoutTimes = 0;//超时20次退出下载。
try
{
System.IO.FileInfo file = new FileInfo(localFullPath);
if (!file.Directory.Exists)
file.Directory.Create();
write = new FileStream(localFullPath, FileMode.Create);
while (true)
{
timeoutObject.Reset();
if (lastReceiveSize < buffersize)
break;
bufferVersion++;
//异步下载
DownloadBytesHandle fh = new DownloadBytesHandle(this.dwonloadBytes);
AsyncCallback callback = new AsyncCallback(this.downloadCallback);
IAsyncResult ar = fh.BeginInvoke(fileName, pos, buffersize, callback, bufferVersion);
if (!timeoutObject.WaitOne(10000))//10秒应能下载完成
{
timeoutTimes++;
Console.Write("_{0}", timeoutTimes); //超时加下划线
if (timeoutTimes > 20)
break;
//超时
if (buffersize > 3000)//10秒无论如何都应能下载1.5K
buffersize = buffersize / 2;//超时下载尺寸减半。
}
else
{
byte[] buffer = fh.EndInvoke(ar);
Console.Write(".");//不断的加点
write.Write(buffer, 0, buffer.Length);
pos += buffer.Length;
lastReceiveSize = buffer.Length;
}
}
isOk = true;
}
catch (Exception ex)
{
isOk = false;
GeneralMethod.HandleException(ex);
}
finally
{
if (write != null)
write.Close();
}
return isOk;
}
public void downloadCallback(IAsyncResult ar)
{
int dbVer = Convert.ToInt32(ar.AsyncState);
if (dbVer == this.bufferVersion)//只有当次调用才释放
timeoutObject.Set();
}
public byte[] dwonloadBytes(string pFileName, long pPosition, int pMaxSize)
{
//System.Threading.Thread.Sleep(11000);//睡11秒。判断是否还会执行。
byte[] buffer = null;
try
{
buffer = Factory.AreaIssueFacade.DownFromTestPool(pFileName, pPosition, pMaxSize);
}
catch { }//忽略所有错误
return buffer;
}
}