Vin*_*erg 0 c# asp.net-mvc asynchronous asp.net-4.5
有没有一种有效的方法来下载文件并以“后台”方式将其保存在磁盘上,而不会阻止当前在mvc控制器中执行某项操作?
目前,我正在使用以下示例代码:
public ActionResult Index()
{
InitiateDownload();
var model = GetModel();
return View(model);
}
private void InitiateDownload()
{
Task.Run(() => DownloadAndSaveFileAsync()).ConfigureAwait(false);
}
private async Task DownloadAndSaveFileAsync()
{
var response = await GetResponse();
using (var fileStream = new FileStream("c:\\file.zip", FileMode.Create, FileAccess.Write, FileShare.None))
{
await response.Content.CopyToAsync(fileStream).ConfigureAwait(false);
}
}
public async Task<HttpResponseMessage> GetResponse()
{
var client = new HttpClient();
client.BaseAddress = new Uri("http://someUrl.com");
return await client.GetAsync("someResourceEndPoint").ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)
我已经读过几个地方,不应在服务器上(在工作线程中)使用Task.Run,因此我想知道此示例是否可扩展(例如,它每秒接收10个请求)还是可靠的,或者是否存在任何适当的方法?如何做到这一点?
谢谢
不会在MVC控制器中阻止当前执行动作?
答案完全取决于您的意思。
如果您打算在下载进行时允许您构建模型,则可以这样简单地进行操作:
public ActionResult Index()
{
var task = DownloadAndSaveFileAsync();
var model = GetModel();
await task;
return View(model);
}
Run Code Online (Sandbox Code Playgroud)
但是,如果您要在不等待下载的情况下将响应返回给客户端,则要复杂得多。我有一篇博客文章,详细介绍了该主题。如果您确实想在完成工作之前返回响应,那么您需要确定该工作对您来说有多重要。
如果需要进行下载,则需要将下载请求放入可靠的队列(例如,Azure队列或MSMQ)中,并有一个独立的后端(例如,Azure工作角色或Win32服务)来进行实际的下载和保存。
如果下载不那么重要-即您的系统可以处理偶尔丢失的下载-那么您可以使用BackgroundTaskManager
上面我的博客文章中的类型:
private void InitiateDownload()
{
BackgroundTaskManager.Run(() => DownloadAndSaveFileAsync());
}
Run Code Online (Sandbox Code Playgroud)
我还建议您BackgroundTaskManager.Shutdown
在下载完成之前关闭AppDomain时使用取消令牌做出适当响应(例如,将消息写入事件日志)。
无论选择哪种解决方案,都应更改DownloadAndSaveFileAsync
为打开文件流以进行异步访问。这是文件流的常见错误;默认情况下,它们是同步的。
归档时间: |
|
查看次数: |
3188 次 |
最近记录: |