现在的位置: 首页 > 综合 > 正文

remoting怪现象。方法长时间不返回,也不报异常。

2012年05月28日 ⁄ 综合 ⁄ 共 3013字 ⁄ 字号 评论关闭

功能:下载文件。

方式:调用Remoting方法,得到整个文件的字节数组,写到本地文件。

代码:

public static bool DownloadFromTestPool(string pFileName, string pLocalFullPath)
{
bool isOk = true;
System.IO.FileStream write = null;
try
{
System.IO.FileInfo file = new FileInfo(pLocalFullPath);
if (!file.Directory.Exists)
file.Directory.Create();

byte[] buffer = Factory.MessionFacade.DownFromTestPool(pFileName);//Factory.MessionFacade为Remoting远程代理
write = new FileStream(pLocalFullPath, FileMode.Create);
write.Write(buffer, 0, buffer.Length);
}
catch (Exception ex)
{
isOk = false;
GeneralMethod.HandleException(ex);
}
finally
{
if (write != null)
write.Close();
}
return isOk;
}

以上方法多次使用都没有问题。但近来出现了一个怪现象。连续下载多个文件时,一般在第三个文件,以下这行代码会长时间无返回,也不抛异常,相当的无奈。

byte[] buffer = Factory.MessionFacade.DownFromTestPool(pFileName);//Factory.MessionFacade为Remoting远程代理

心想是不是一次的字节数组过大,在某些公网的情况下会有问题呢? 改为使用断点分次下载,情况依旧。由于方法是长时间不返回且无异常,只好利用异步超时的方式去检测这种情况,并重新调用Remoting方法方法。

断点分次异步重连

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

 

利用上面的代码,下载4个文件,以下是过程日志。每一个点代表一次成功调用,下划线代表超时,下划线后面的数字代表第几次超时。

开始从发布服务器下载文件..
下载HIS.Mattgr.UI.dll.......... 从发布服务器下载成功
下载HIS.Mattgr.Services.dll............ 从发布服务器下载成功
下载HIS.Mattgr.Interface.dll_1_2_3......... 从发布服务器下载成功
下载HIS.PublicMattgr.Services.dll......... 从发布服务器下载成功

每次的日志都显示在第三个文件一开始都会有连续的三次调用超时,而之后又会很快。真走运,如此稳定的异常情况。

抱歉!评论已关闭.