[英]How can I redirect to another action from my Asynchronous Action in MVC4
I am currently trying to write some code that will accept some FTP details, get a file list, then allow the user to download the files. 我目前正在尝试编写一些代码,这些代码将接受一些FTP详细信息,获取文件列表,然后允许用户下载文件。
This all works fine, except that I have to wait for the files to finished downloading before it will do anything. 一切正常,除了我必须等待文件完成下载之后才能执行任何操作。 I am using an Asynchronous controller as I thought this was meant to help with this sort of thing.
我正在使用异步控制器,因为我认为这旨在帮助解决此类问题。
Please see a selection of my code below, I have left out all the code thats not relevant: 请在下面查看我的代码选择,我遗漏了所有与代码无关的代码:
[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();
}
It fires the FtpCompleted action perfectly fine, but the problem is this is meant to handle file transfers of potentially GB's of information. 它可以很好地触发FtpCompleted操作,但是问题是这意味着要处理潜在GB信息的文件传输。 I dont want the user to sit watching a spinning disc while they wait for the files to be downloaded.
我不希望用户在等待文件下载时坐下来观看旋转的光盘。 Hence the reason I was trying to redirect them to the Transfer Action, this action just displays a message telling them that the transfer may take a while and they will be notified once its complete.
因此,我尝试将他们重定向到“转移操作”的原因是,该操作仅显示一条消息,告诉他们转移可能需要一段时间,一旦转移完成,就会通知他们。 However this action never actually gets called.
但是,此操作实际上从未被调用。 I step through the code in debug and it calls it, but it never displays the message and it never gets to the browser according to FireBug.
我逐步调试了代码,并对其进行了调用,但是根据FireBug的说法,它从不显示消息,也不会到达浏览器。
Am I doing something stupid or is it just not possible to do this? 我是在做一些愚蠢的事情,还是只是做不到?
I would be grateful for any assistance people can offer here as I am completely stuck after browsing google and other posts on here. 我会很感激人们在这里可以提供的任何帮助,因为在浏览google和此处的其他帖子后,我完全陷入了困境。 Even my boss who is a much more experienced coder isnt sure how to handle this.
即使是经验丰富的编码员,我的老板也不确定该如何处理。
Thanks in advance, 提前致谢,
Gaz 加兹
As explained in the documentation an asynchronous controller action consists of 2 methods: 如文档中所述,异步控制器操作包含2种方法:
Async
suffix and the action name prefix Async
后缀和操作名称前缀的方法 Completed
suffix and the action name prefix Completed
后缀和操作名称前缀的方法 The first method triggers asynchronous operation and returns immediately. 第一种方法触发异步操作并立即返回。 The second method is invoked once the entire operation has completed.
整个操作完成后,将调用第二种方法。
So here's are the correct action signatures: 所以这是正确的动作签名:
[HttpPost]
public void FtpAsync(Downloads model)
{
...
}
public ActionResult FtpCompleted(Downloads model)
{
return Content("Complete");
}
Now, if you don't want to freeze the browser during the entire operation you will have to invoke the first controller action using AJAX. 现在,如果您不想在整个操作过程中冻结浏览器,则必须使用AJAX调用第一个控制器操作。 Asynchronous controllers do not change anything in terms of the HTTP protocol.
异步控制器不会根据HTTP协议进行任何更改。 From the client perspective it is absolutely the same.
从客户的角度来看,这是绝对相同的。 The only difference with a standard controller action is that you are not jeopardizing a worker thread during the entire operation.
与标准控制器操作的唯一区别是,在整个操作过程中,您不会危害工作线程。 You are now relying on the IOCP (IO/Completion Ports) that are an OS artifact used by the
WebClient
. 现在,您依赖IOCP(IO /完成端口),它是
WebClient
使用的OS工件。 The idea is that when you start an IO intensive operation, an IOCP port is created and the controller action immediately returns the thread to the ASP.NET thread pool. 这个想法是,当您开始进行IO密集型操作时,将创建IOCP端口,并且控制器操作会立即将线程返回到ASP.NET线程池。 Then the operation could last for hours, and once it completes the IOCP is signaled, a pool is drawn from the thread pool and the Completed action is invoked on this thread.
然后该操作可能持续数小时,一旦完成IOCP信号,就会从线程池中提取一个池,并在该线程上调用Completed操作。 So in terms of threads it is very effective.
因此在线程方面非常有效。 But the total time of execution is absolutely the same as if you have used a standard controller action.
但是执行的总时间与使用标准控制器操作绝对相同。 Many people think that because Asynchronous Controller are called Asynchronous they run asynchronously from the client perspective.
许多人认为,由于异步控制器被称为异步,因此它们从客户端角度异步运行。 That's a false impression.
这是一个错误的印象。 Asynchronous actions don't make your operations miraculously run faster.
异步操作不会使您的操作奇迹般地运行得更快。 They are still perfectly synchronous from the client perspective, because that's how the HTTP protocol works.
从客户端的角度来看,它们仍然是完全同步的,因为这就是HTTP协议的工作方式。
So you have 2 possibilities: 因此,您有2种可能性:
The second approach is recommended if you want a really effective solution. 如果您想要一个真正有效的解决方案,则建议使用第二种方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.