C# MultipartFormDataStreamProvider和在上传文件后立即读取文件有时会失败

C# MultipartFormDataStreamProvider和在上传文件后立即读取文件有时会失败,c#,asp.net-web-api,C#,Asp.net Web Api,我有一些Web API代码,这些代码是我从SO帖子和其他网站汇编而来的。然而,任务的东西对我来说仍然是新的。我试图将上传的文件复制到一个新位置,但有时(并非所有时间)我在复制文件时会出现异常。异常表示该文件正由另一个进程使用。但这并不是每次都会发生。我想我需要将复制操作移到其他地方。这是我的密码。有什么建议吗 var provider = new MultipartFormDataStreamProvider(uploadroot); var task = Req

我有一些Web API代码,这些代码是我从SO帖子和其他网站汇编而来的。然而,任务的东西对我来说仍然是新的。我试图将上传的文件复制到一个新位置,但有时(并非所有时间)我在复制文件时会出现异常。异常表示该文件正由另一个进程使用。但这并不是每次都会发生。我想我需要将复制操作移到其他地方。这是我的密码。有什么建议吗

var provider = new MultipartFormDataStreamProvider(uploadroot);
                var task = Request.Content.ReadAsMultipartAsync(provider).ContinueWith<HttpResponseMessage>(t =>
                {
                    if (t.IsFaulted || t.IsCanceled)
                        throw new HttpResponseException(HttpStatusCode.InternalServerError);

                    var docConversionId = Guid.NewGuid().ToString("N");
                    var sourceFilePath = Path.Combine(uploadroot, provider.FileData.First().LocalFileName);
                    var destinationFilePath = Path.Combine(inboxroot, docConversionId);

                    File.Copy(sourceFilePath, destinationFilePath);

                    var response = new HttpResponseMessage(HttpStatusCode.OK);
                    response.Content = new StringContent(docConversionId);
                    //response.Content.Headers.Add("DocumentConversionId", docConversionId);
                    return response;
                });
                return task;
var provider=新的MultipartFormDataStreamProvider(uploadroot);
var task=Request.Content.ReadAsMultipartAsync(提供程序).ContinueWith(t=>
{
如果(t.IsFaulted | | t.IsCanceled)
抛出新的HttpResponseException(HttpStatusCode.InternalServerError);
var docConversionId=Guid.NewGuid().ToString(“N”);
var sourceFilePath=Path.Combine(uploadroot,provider.FileData.First().LocalFileName);
var destinationFilePath=Path.Combine(inboxroot,docConversionId);
Copy(sourceFilePath,destinationFilePath);
var响应=新的HttpResponseMessage(HttpStatusCode.OK);
response.Content=新的StringContent(docConversionId);
//response.Content.Headers.Add(“DocumentConversionId”,docConversionId);
返回响应;
});
返回任务;

在使用ReadAsMultipartAsync后,立即尝试读取/删除文件可能会遇到已知问题

以下是与此相关的错误(您可以查看解决方案信息,了解其发生原因以及解决方法的更多详细信息):


我遇到了这个严重的问题,发现它与
wait
关键字一起工作

await Request.Content.ReadAsMultipartAsync(streamProvider);

没有将任务保存在变量中。

由于codeplex中的原始讨论已经结束,我将在2013年最初关闭该问题时的原始解释和解决方法粘贴到这里:

我们正在关闭此问题,因为发现根本原因在 框架代码。一个单独的bug已针对外部服务器打开 合作伙伴团队,此问题将在那里跟踪

变更集:

恢复尝试的修复,其中我们使用FileOptions.WriteThrough进行了修复 确保它不是文件缓存和FileStream代码之间的竞争。 但是WriteThrough没有解决核心缺陷,导致性能下降 退化

对用户代码的影响是这样的:如果您使用 MultipartFormDataContent并在服务器上使用 MultiPartDataStreamProvider,服务器上的基础文件可能不可用 在ReadAsMultipartAsync完成后完全关闭。有一个 本机代码可能仍在释放文件资源的小窗口 在另一个线程上

其影响是对该文件执行File.Delete或File.OpenRead 异步读取之后可能会立即失败,并出现IOException(“文件 正在被另一个进程使用”)。我们在试验中观察到约0.3%的故障率 高负载情况。唯一已知的解决方法是尝试/抓住 在这些操作中,如果发生IOException,则延迟一小段时间, 然后重试。50毫秒延迟通常有效,但允许多次延迟 建议重试。这允许本机线程完成 释放资源。在我们的压力实验室里,这个 捕获延迟和重试算法始终成功


你得到的例外是什么?发生在哪行代码上?对不起,我赶时间。周末去了一趟小旅行。我无法复制该文件,因为另一个进程正在使用该文件。这可能是我正在处理的问题。谢谢链接已断开。您能提供一个解决方法吗?在整个WebAPI项目中使用async/await会很好,但是,在本例中,.NET framework代码存在一个已知的bug,该bug会对上载的文件进行锁定。当时我的解决方法是使用重试计数器执行一个简单的for循环,捕获与文件锁相关的异常,然后休眠并重试。我不知道这个bug是否已经修复(我当然希望已经修复了!)。如果不是,像Polly这样的库可能是比滚动您自己的重试循环更好的解决方案。我想某处有一只虫子。使用wait时,文件始终被释放,可以移动或删除。