C# 进程无法访问该文件,因为其他进程正在使用该文件

C# 进程无法访问该文件,因为其他进程正在使用该文件,c#,streamwriter,system.io.file,C#,Streamwriter,System.io.file,我正在努力做到以下几点: var path = Server.MapPath("File.js")); // Create the file if it doesn't exist or if the application has been restarted // and the file was created before the application restarted if (!File.Exists(path) || ApplicationStartTime > File

我正在努力做到以下几点:

var path = Server.MapPath("File.js"));

// Create the file if it doesn't exist or if the application has been restarted
// and the file was created before the application restarted
if (!File.Exists(path) || ApplicationStartTime > File.GetLastWriteTimeUtc(path)) {
    var script = "...";

    using (var sw = File.CreateText(path)) {
        sw.Write(script);
    }
}
但是,有时会抛出以下错误:

进程无法访问文件“…\file.js”,因为它正在运行 被另一个进程使用

我在这里看到了类似的问题,但我的问题似乎与其他问题略有不同。此外,在服务器负载过重之前,我无法复制它,因此我希望在上传修复之前确保它是正确的

如果有人能告诉我如何解决这个问题,我将不胜感激


谢谢

听起来好像有两个请求同时在您的服务器上运行,它们都试图同时写入该文件

您需要添加某种锁定行为,或者编写一个更健壮的体系结构。在不了解更多关于这个文件编写过程实际要完成什么的情况下,我建议最好的方法是锁定。我通常不喜欢在web服务器上使用这种锁定,因为它会使请求相互依赖,但这会解决问题


编辑:德克在下面指出,这可能有效,也可能无效。根据您的web服务器配置,可能不会共享静态实例,并且可能会出现相同的结果。我将此作为概念证明,但您应该最明确地解决根本问题



但是,再一次,我很想重新考虑一下你到底想用这个来完成什么。也许您可以在
应用程序\u Start
方法中构建此文件,甚至可以只构建一个静态构造函数。对每个请求都这样做是一种混乱的方法,很可能会导致问题。特别是在重载情况下,每个请求都将被迫同步运行。

应用程序是否按需/多次运行?您可能需要一个互斥锁来保护文件访问。如果两个请求大致在同一时间到达,两个IIS线程可以尝试同时写入文件并互相攻击。您可以实现某种锁定,但我建议您不要采用这种策略——也许您可以编写一个处理程序来动态生成脚本,而不是每隔一段时间将脚本写入磁盘?@helb这是一个web应用程序,此代码会在每次请求时触发。您尝试过sw.Close()?我知道using语句正在自动关闭文件。但为了确保这一点,您必须保护相互访问,因为您的应用程序可能会并行运行多次。我不是web服务器方面的专家,但如果服务器使用多个应用程序域,那么这将不起作用,因为每个应用程序域都有自己的静态实例。@Dirk啊,很有趣。我没有想到这一点,这是一个很好的观点。正如我所说,我从来没有真正这样做过,这只是一个概念的证明。但是是的,如果这是真的(我相信),那么将这段代码放到只运行一次的代码中是绝对值得的。您可以使用命名互斥锁而不是标准锁。这甚至可以跨越流程边界。谢谢,我采纳了您的建议,并将代码移到了应用程序启动事件中。
private static object lockObj = new object();

private void YourMethod()
{
    var path = Server.MapPath("File.js"));

    lock (lockObj)
    {
        // Create the file if it doesn't exist or if the application has been restarted
        // and the file was created before the application restarted
        if (!File.Exists(path) || ApplicationStartTime > File.GetLastWriteTimeUtc(path))
        {
            var script = "...";

            using (var sw = File.CreateText(path))
            {
                sw.Write(script);
            }
        }
    }
}