C# FileLoadException:文件正在使用中

C# FileLoadException:文件正在使用中,c#,uwp,C#,Uwp,我的任务是将每秒30次来自传感器的数据写入.csv文件。如果sersor发送了错误的数据,我不写它,只是等待。如果数据再次正常,我需要创建一个新文件并开始在那里写入数据。这是我的密码: class FileWriter { string filename; public FileWriter() { } public void SetFilename(string filename) { this.filename = fil

我的任务是将每秒30次来自传感器的数据写入
.csv
文件。如果sersor发送了错误的数据,我不写它,只是等待。如果数据再次正常,我需要创建一个新文件并开始在那里写入数据。这是我的密码:

class FileWriter
{
    string filename;

    public FileWriter()
    {

    }

    public void SetFilename(string filename)
    {
        this.filename = filename;
    }

    public async void WriteData(string data)
    {

        StorageFile file = await KnownFolders.PicturesLibrary.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);

        var stream = await file.OpenAsync(FileAccessMode.ReadWrite);
        using (var outputStream = stream.GetOutputStreamAt(stream.Size))
        {
            using (var dataWriter = new Windows.Storage.Streams.DataWriter(outputStream))
            {
                dataWriter.WriteString(data);

                await dataWriter.StoreAsync();

            }
            await outputStream.FlushAsync();
        }
        stream.Dispose();
    }

}
但我总是得到:

Exception thrown: 'System.IO.FileLoadException' in 
System.Private.CoreLib.ni.dll
WinRT information: The file is in use. Please close the file before continuing.
FileLoadException: The process cannot access the file because it is being used by another process.
我认为,这是因为文件是异步打开的,没有时间每秒打开30次。但我不知道如何修复它

编辑:更多详细信息。
我拿了。有一个类
SpatialMappingServer
,它有一个方法
Update()
,每秒调用30次。在那里,我调用我的
WriteData()
将Hololens相机的状态写入文件中。因为
Update()
不是异步的,所以我不能调用
wait WriteData()

您应该使用锁来确保在给定时间只有一个线程在写入文件,如下所示:

class FileWriter
{
    static readonly object _filelock = new object();
    string filename;

    public FileWriter()
    {

    }

    public void SetFilename(string filename)
    {
        this.filename = filename;
    }

    public async void WriteData(string data)
    {
        lock (_filelock) 
        {

            StorageFile file = await KnownFolders.PicturesLibrary.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists);

            using(var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
            {
                using (var outputStream = stream.GetOutputStreamAt(stream.Size))
                {
                    using (var dataWriter = new Windows.Storage.Streams.DataWriter(outputStream))
                    {
                        dataWriter.WriteString(data);

                        await dataWriter.StoreAsync();

                    }
                    await outputStream.FlushAsync();
                }
            }
        }
    }
}

另外,我认为您的CreationCollisionOption必须设置为OpenIfExists。

您可以将对WriteData的调用添加到问题中吗?你等了吗?是的,我直接调用
WriteData()
而不等待它。我没有同步。这意味着我在C#方面知识薄弱。我只是不知道如何正确地执行它。在使用相同的文件名再次调用它之前,您需要确保上次WriteData方法调用已完成。要做到这一点,您至少需要等待WriteData调用,但这可能还不够。你知道触发写操作的代码吗?此外,如果要在没有错误的情况下在同一文件中多次写入,则需要将CreationCollisioOption标志更改为OpenIfExists。(我会相应地更新我的答案)看起来我们真的可以确定当更新发生时,在这种情况下,你可以使用锁。我更新了我的答案。最后,添加以下代码(如果您使用的是C#,则在内部using语句中)以使用DataWriter.StoreAsync将文本保存到文件中,并使用IOutputStream.FlushAsync关闭流。C#Copy wait dataWriter.StoreAsync();等待outputStream.FlushAsync();我看到您的代码可能出现许多问题,但是我怀疑问题不在您发布的行内。对于那些——首先也是最重要的——您使用的是async void,这是不好的,我还怀疑您可能会尝试像WriteData()一样以fire forget的方式运行它,而不等待它。第二件事是-为什么不把
var-stream
也放在using语句中,然后手动处理呢?至于错误的原因,您是否尝试将数据多次写入同一个文件?如果是这样,为什么每次都要创建文件?您不能创建一次文件,将流保存到其中,并在需要时写入吗?另一种设计可能是缓冲数据并以一定的间隔写入。至于异步-您是否使用任何同步对象来防止竞争条件/保护文件?然而,为了得到答案,你需要发布更多的代码,特别是调用WriteData的位置和方式。是的,我直接调用
WriteData()
,而不等待它。我没有同步。这意味着我在C#方面知识薄弱。我只是不知道如何正确操作。@Romasz是对的,你可以用一个using语句替换下面的try…finally,它们是等价的,但是using要短得多。