我是MVC的新手,我正在尝试为网站创建一个下载页面,但遇到了问题。该页面包含许多可用文件,您可以在单击与其关联的按钮时下载该文件。
当收到下载请求时,将通过块中的套接字从远程服务器检索文件并将其写入响应流。当只有一个请求时,一切正常,但如果双击或其他用户同时发出请求,则会全部纠结。
问题是我如何对请求进行排队,以便在第二次和后续请求被执行之前完成一个下载请求。
感谢任何想法或帮助。
这是下载行动
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Download(string itemID)
{
System.Diagnostics.Debug.WriteLine("DOWNLOAD REQUEST");
var downloadReq = new DownloadInfo() { ID = Convert.ToInt64(itemID), CurrentBlockNum = -1 };
var username = User.Identity.Name;
var request = new IDeskPacket(PacketType.Download, username, downloadReq);
//get the first block of data
var ideskResponse = (IDeskPacket)await RequestChannel.Instance.SendAync(request);
if (ValidResponse(ideskResponse))
{
//initialise data
var downloadInfo = (DownloadInfo)ideskResponse.Data;
bool flush = false;
//build the response stream
Response.Clear();
if (!Response.IsClientConnected)
{
System.Diagnostics.Debug.WriteLine("DOWNLOAD REQUEST FINISHED - DISCONNECTED");
Response.End();
return View("Error");
}
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=" + GetshortFilename(downloadInfo.Filename));
Response.AddHeader("Content-Length", downloadInfo.FileSize.ToString());
try
{
//loop until the end of the data or an invalid response
do
{
//write the received data to the response stream
Response.BinaryWrite(downloadInfo.DataBlock);
//null the data block out so it doesn't get sent back to the server later
downloadInfo.DataBlock = null;
//so we don't cache to much flush after every "other" data request
if (flush) Response.Flush();
flush = !flush;
//send request for next block of data
ideskResponse = (IDeskPacket)await RequestChannel.Instance.SendAync(ideskResponse);
//check the response and cache the data if valid
if (ValidResponse(ideskResponse)) downloadInfo = (DownloadInfo)ideskResponse.Data;
} while (downloadInfo.CurrentBlockNum > 0);
}
catch (HttpException httpEx)
{
System.Diagnostics.Debug.WriteLine(httpEx.Message);
//Response.Clear();
}
//signal the end of the response stream
Response.End();
System.Diagnostics.Debug.WriteLine("DOWNLOAD REQUEST FINISHED - FILE DOWNLOAD FINISHED");
return View("Index", "UserDownload");
}
else
{
//redirect to error
System.Diagnostics.Debug.WriteLine("DOWNLOAD REQUEST FINISHED - INVALID SERVER RESPONSE");
return View("Error");
}
}
答案 0 :(得分:0)
您可以使用Delegates构建队列和用户BeginInvoke,以便它可以异步处理您的请求,例如我为邮件发送构建了一个委托:
delegate bool MailSender(string to, string cc, string subject, string message);
public static void SendMailAsync(string to, string cc, string subject, string message)
{
MailSender sender = new MailSender(SendMail);
AsyncCallback callback = new AsyncCallback(DisposeMail);
sender.BeginInvoke(to, cc, subject, message, callback, "");
}
private static void DisposeMail(IAsyncResult result)
{
AsyncResult delegateResult = (AsyncResult)result;
MailSender delegateInstance = (MailSender)delegateResult.AsyncDelegate;
delegateInstance.EndInvoke(result);
}
Where&#34; SendMail&#34; ius是一个负责在你的情况下远程下载所需处理的函数,但这将被委托称为async。希望这有帮助