我正在尝试取消下载操作。我的方案如下:
当用户点击取消下载按钮时,此操作会在下载功能中抛出异常,如下所示:
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 (response != null)
{
outputStream.Close();
ftpStream.Close();
response.Close();
}
return false;
}
在这里引发异常的行“ftpStream.Close()
”中......
例外文字是:
远程服务器返回错误: (450)文件不可用(例如,文件 忙)
它打开一个要下载的文件,因为我写的是“outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);
”我不会关闭此流并按顺序关闭响应,如果用户执行如下操作:
下载 - >取消下载 - >下载 - >取消下载 - >下载
如果发生这种情况,应用程序就会挂起。我不知道如何关闭流和响应,所以我可以停止下载然后删除创建的文件,以便再次下载。
日Thnx
答案 0 :(得分:3)
似乎导致您执行的行是下面的行,这是由于FTP服务器找不到您想要的文件。这种情况可能很容易再次发生,因此可能值得在该单独的行周围放置一个try / catch块,或者使用它正在生成的特定异常的catch。
ftpStream = response.GetResponseStream();
在catch块中,您正在使用outputStream.Close(),但如果上面的行发生异常,则outputStream将为null。至少你应该改变在catch块中关闭对象的顺序,并检查它们是否为null。
if(response != null) {
response.Close();
}
if(ftpStream != null) {
ftpStream.Close();
}
if(outputStream != null) {
outputStream.Close();
}
答案 1 :(得分:1)
首先关闭,将你的关闭放在finally块中。
因此,请确保您的代码是这样的,以确保无论如何都会关闭流。
try
{
//Your existing logic
//Don't need to close the streams/etc
}
catch
{
//Just do what you need to with the exception
}
finally
{
//This is always called
if (response != null)
response.Close();
if(outputStream != null)
outputStream.Close();
if(ftpStream != null)
ftpStream.Close();
}
在try catch
中包装此行ftpStream = response.GetResponseStream();
只要调用那些Close调用,你的取消逻辑在哪里就可以了?我希望在用户单击按钮时设置循环上的标志。 e.g。
while (readCount > 0 && !_shouldExit)
{
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);
}