我的应用程序功能之一是从我们的ftp服务器下载文件。当然,此功能会重新启动以取消此操作(取消下载)。
现在,我的下载功能如下:
try
{
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + uri + "/" + fileName));
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
reqFTP.UsePassive = true;
response = (FtpWebResponse)reqFTP.GetResponse();
ftpStream = response.GetResponseStream();
_isItOutputStream = true;
string dataLengthString = response.Headers["Content-Length"];
int dataLength = 0;
if (dataLengthString != null)
{
dataLength = Convert.ToInt32(dataLengthString);
}
long cl = response.ContentLength;
int bufferSize = 4048;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = ftpStream.Read(buffer, 0, bufferSize);
outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);
bool first = true;
while (readCount > 0)
{
outputStream.Write(buffer, 0, readCount);
_actualDownloaded += readCount;
if (this.InvokeRequired)
{
ProgressBarDel _progressDel = new ProgressBarDel(ProgressBar);
this.Invoke(_progressDel, new object[] { _actualDownloaded, first });
}
first = false;
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
ftpStream.Close();
outputStream.Close();
response.Close();
_isItOutputStream = false;
return true;
}
catch (Exception ee)
{
_downloadException = ee.Message;
if (ftpStream != null && outputStream!=null )
if (ftpStream.CanRead && outputStream.CanWrite)
{
ftpStream.Close();
outputStream.Close();
}
if (response != null)
response.Close();
return false;
}
现在您可以在Catch Block中看到,当用户点击“取消”按钮时,我正在尝试中断此连接。
1)点击取消按钮。
2)调用函数“DoSomeWorx()”
3)在“DoSomeWorx()”中执行:
if (_isItOutputStream)// where here i'm trying to check if it's downloading
{
ftpStream.Close();
outputStream.Close();
response.Close();
}
if (_startCopy)// check if copying to phone
{
IsCancelled();
}
_btnDownload2PhoneThread.Abort(); // actually this operation does what i did before but for some resoans it does this but it takes time...
_btnDownload2PhoneThread.Join();
问题是当我达到以下任何一项(ftpStream.Close();outputStream.Close();response.Close();)
它抛出异常“文件不可用(例如文件繁忙)”
并且此异常会影响重新下载操作,因为它会看到文件繁忙。
那么如何避免这种异常?
答案 0 :(得分:4)
我假设您有某种形式,所以您在线程上执行下载。
你最好做的就是检查你的while循环中的“取消”标志。
例如
while(readcount > 0 && !cancel)
{
...
}
然后让你的方法优雅地取消。
其次,您应该在流上使用using语句。这意味着如果你抛出一个异常,finally块将保证你的流被处理掉(这就是为什么你要接收文件繁忙的原因,因为即使你的方法已经完成,流还没有运行析构函数)