服务大文件异步,然后删除它

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# 编译器,因此它可能无法编译,但我想您明白了。