服务大文件异步,然后删除它
Serve large file async and then delete it
使用 Web API 2,我有一个生成临时文件的进程,目的是将其写入输出流以供客户端使用。该过程可能会有点长 运行,需要几分钟才能完成。
我想做的是异步提供文件,然后在完成或取消(连接超时)时将其删除。
这样的事情会很接近吗?我还没有测试过,但我想知道 continue 会在文件完全提供之前删除文件。
public class FileCreationResult
{
public String FilePathOut { get; set; }
}
public class MyFileCreationProcess{
const string NaiveDefaultTempFilePath = @"c:\temp\mytempfile.bin";
public FileCreationResult Execute(){
// do stuff that makes a file
File.WriteAllBytes(NaiveDefaultTempFilePath, NaiveDefaultTempFilePath);
return new FileCreationResult{
FilePathOut = NaiveDefaultTempFilePath
};
}
}
public class Controller : ApiController
{
private readonly MyFileCreationProcess process;
public Controller(MyFileCreationProcess process)
{
this.process = process;
}
public async Task<HttpResponse> GetFile(CancellationToken cancellationToken){
return await Task.Run(()=>{
var fileCreationResult = process.Execute();
using( var stream = File.OpenRead(fileCreationResult.FilePathOut)){
var response = Request.CreateResponse();
response.Content = new StreamContent( stream);
return response;
//
// I would like to delete the file at path fileCreationResult.FilePathOut
// after it has been written to the output stream..
// how would I do this ?
}
});
}
}
你可能只需尝试 finally 块就可以逃脱
public async Task<HttpResponse> GetFile(CancellationToken cancellationToken){
return await Task.Run(()=>{
var fileCreationResult = process.Execute();
try{
using( var stream = File.OpenRead(fileCreationResult.FilePathOut)){
var response = Request.CreateResponse();
response.Content = new StreamContent( stream);
return response;
}
}finally{
if(File.Exists(fileCreationResult.FilePathOut))
{
File.Delete(fileCreationResult.FilePathOut);
}
}
});
}
或者如果你想使用 continueWith
:
public Task<HttpResponse> GetFile(CancellationToken cancellationToken){
string path;
return Task.Run(()=>{
var fileCreationResult = process.Execute();
path = fileCreationResult.FilePathOut;
using( var stream = File.OpenRead(path)){
var response = Request.CreateResponse();
response.Content = new StreamContent( stream);
return response;
}
}).ContinueWith(x=>{
if(File.Exists(fileCreationResult.FilePathOut))
{
File.Delete(fileCreationResult.FilePathOut);
}
});
}
请注意,我手边没有 C# 编译器,因此它可能无法编译,但我想您明白了。
使用 Web API 2,我有一个生成临时文件的进程,目的是将其写入输出流以供客户端使用。该过程可能会有点长 运行,需要几分钟才能完成。
我想做的是异步提供文件,然后在完成或取消(连接超时)时将其删除。
这样的事情会很接近吗?我还没有测试过,但我想知道 continue 会在文件完全提供之前删除文件。
public class FileCreationResult
{
public String FilePathOut { get; set; }
}
public class MyFileCreationProcess{
const string NaiveDefaultTempFilePath = @"c:\temp\mytempfile.bin";
public FileCreationResult Execute(){
// do stuff that makes a file
File.WriteAllBytes(NaiveDefaultTempFilePath, NaiveDefaultTempFilePath);
return new FileCreationResult{
FilePathOut = NaiveDefaultTempFilePath
};
}
}
public class Controller : ApiController
{
private readonly MyFileCreationProcess process;
public Controller(MyFileCreationProcess process)
{
this.process = process;
}
public async Task<HttpResponse> GetFile(CancellationToken cancellationToken){
return await Task.Run(()=>{
var fileCreationResult = process.Execute();
using( var stream = File.OpenRead(fileCreationResult.FilePathOut)){
var response = Request.CreateResponse();
response.Content = new StreamContent( stream);
return response;
//
// I would like to delete the file at path fileCreationResult.FilePathOut
// after it has been written to the output stream..
// how would I do this ?
}
});
}
}
你可能只需尝试 finally 块就可以逃脱
public async Task<HttpResponse> GetFile(CancellationToken cancellationToken){
return await Task.Run(()=>{
var fileCreationResult = process.Execute();
try{
using( var stream = File.OpenRead(fileCreationResult.FilePathOut)){
var response = Request.CreateResponse();
response.Content = new StreamContent( stream);
return response;
}
}finally{
if(File.Exists(fileCreationResult.FilePathOut))
{
File.Delete(fileCreationResult.FilePathOut);
}
}
});
}
或者如果你想使用 continueWith
:
public Task<HttpResponse> GetFile(CancellationToken cancellationToken){
string path;
return Task.Run(()=>{
var fileCreationResult = process.Execute();
path = fileCreationResult.FilePathOut;
using( var stream = File.OpenRead(path)){
var response = Request.CreateResponse();
response.Content = new StreamContent( stream);
return response;
}
}).ContinueWith(x=>{
if(File.Exists(fileCreationResult.FilePathOut))
{
File.Delete(fileCreationResult.FilePathOut);
}
});
}
请注意,我手边没有 C# 编译器,因此它可能无法编译,但我想您明白了。