我目前正在尝试编写一些代码来接受一些FTP细节,获取文件列表,然后允许用户下载文件。
这一切都很好,除了我必须等待文件完成下载才会做任何事情。我正在使用异步控制器,因为我认为这是为了帮助解决这类问题。
请在下方查看我的代码选择,我遗漏了所有不相关的代码:
[HttpPost]
public ActionResult FtpAsync(Downloads model)
{
var ftpAddress = model.Url;
if (!ftpAddress.StartsWith("ftp://"))
ftpAddress = String.Concat("ftp://", ftpAddress);
var serverPath = Server.MapPath(ThumbnailSupport.CreateBaseVirtualPathForClient(StandardFileLinks.DropBoxLocation,
_website.Client));
if (!Directory.Exists(serverPath))
Directory.CreateDirectory(serverPath);
foreach (string file in model.SelectedFiles)
{
var webClient = new WebClient();
AsyncManager.OutstandingOperations.Increment();
AsyncManager.Parameters["FilesToDownload"] = model.SelectedFiles;
webClient.Credentials = new NetworkCredential(model.Username, model.Password);
webClient.DownloadFileAsync(new Uri(ftpAddress + "/" + file), serverPath + "\\" + file);
AsyncManager.OutstandingOperations.Decrement();
}
return RedirectToAction("Transfer");
}
public ActionResult FtpCompleted(Downloads model)
{
return RedirectToAction("Complete");
}
public ActionResult Transfer()
{
return PartialView();
}
它完全解除了FtpCompleted操作,但问题是这是为了处理潜在GB信息的文件传输。我不希望用户在等待下载文件时坐着观看旋转的光盘。因此,我试图将它们重定向到转移操作的原因,此操作只显示一条消息,告诉他们转移可能需要一段时间,一旦完成,它们将会收到通知。然而,这个动作实际上从未被调用。我在调试中单步执行代码并调用它,但它从不显示消息,并且根据FireBug它永远不会到达浏览器。
我做了些蠢事还是不可能做到这一点?
我很感激人们可以在这里提供任何帮助,因为我在这里浏览谷歌和其他帖子后完全陷入困境。即使我的老板是一位经验更丰富的编码员,也不确定如何处理这个问题。
提前致谢,
达伽兹
答案 0 :(得分:1)
如documentation中所述,异步控制器操作由2个方法组成:
Async
后缀和操作名称前缀Completed
后缀和操作名称前缀第一种方法触发异步操作并立即返回。整个操作完成后,将调用第二种方法。
所以这是正确的行动签名:
[HttpPost]
public void FtpAsync(Downloads model)
{
...
}
public ActionResult FtpCompleted(Downloads model)
{
return Content("Complete");
}
现在,如果您不想在整个操作期间冻结浏览器,则必须使用AJAX调用第一个控制器操作。异步控制器不会根据HTTP协议进行任何更改。从客户的角度来看,它绝对是一样的。与标准控制器操作的唯一区别在于,您不会在整个操作期间危害工作线程。您现在依赖的是WebClient
使用的操作系统工件的IOCP(IO /完成端口)。我们的想法是,当您启动IO密集型操作时,会创建一个IOCP端口,并且控制器操作会立即将该线程返回到ASP.NET线程池。然后,该操作可能持续数小时,并且一旦完成IOCP信号,就会从线程池中抽取池,并在此线程上调用Completed操作。所以就线程而言,这是非常有效的。但是执行的总时间与使用标准控制器操作完全相同。许多人认为,因为异步控制器被称为异步,所以它们从客户端角度异步运行。这是一种错误的印象。异步操作不会使您的操作奇迹般地运行得更快。从客户端的角度来看,它们仍然完全同步,因为这就是HTTP协议的工作方式。
所以你有两种可能性:
如果您想要一个非常有效的解决方案,建议使用第二种方法。