【问题标题】:Access a file created by a separate thread访问由单独线程创建的文件
【发布时间】:2011-12-14 04:37:19
【问题描述】:

我在复制和访问文件时遇到了多线程问题。

我有一项服务,它会下载并解压缩 Zip 存档,然后将文件从解压缩的文件夹复制到正确的位置:

//Download, and uzip archive...

//Copy a needed file to its right location
File.Copy(fileName, fileDestination);

然后我启动一个单独的线程,它需要访问复制的文件:

TheadPool.QueueUserWorkItem(s => processCopiedFile(fileDestination));

这是来自 ProcessCopiedFile 的代码片段:

private void ProcessCopiedFile(string filePath)
{
    ...
    //Load the file, previously copied here
    var xml = XDocument.Load(filePath);
    ...
    //Do other work...
}

XDoument.Load 调用失败并出现异常:

The process cannot access the file <FileName> because it is used by another process.

似乎 File.Copy 使结果文件保持锁定状态。当所有工作同步进行时,它可以正常工作。 你有什么想法吗? 谢谢。

【问题讨论】:

    标签: c# multithreading io file-copying


    【解决方案1】:

    File.Copy 不会保持任何打开或锁定,它是一个原子操作,需要一些时间,当然取决于磁盘/网络 I/O 和文件大小。

    当然,在从同步移动到异步时,您应该确保在复制仍在进行时不要访问目标文件。

    【讨论】:

    • 首先我调用 File.Copy(同步),然后我开始新的线程。因为 File.Copy 被同步调用,它保证在新线程启动之前完成它的工作。还是我在某个地方弄错了?
    • +1 - 只是为了澄清最后一部分:Windows 在文件被复制时保持对文件的独占锁定。
    【解决方案2】:

    使用流复制文件以避免 File.Copy 锁定窗口

    using(var s = new MemoryStream(File.ReadAllBytes(filePath))
    {
        using(var fs = new FileStream(newLocation, FileMode.Create))
        {
            s.WriteTo(fs);
        }
    }
    

    【讨论】:

    • 正确复制文件是火箭科学。需要注意在文件中保留文件属性和备用流。不要自己做。
    猜你喜欢
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    相关资源
    最近更新 更多