0
votes

I got some intermit exceptions to write texts to a brand new file in one of my UWP application. The sample codes look like

var myFolder = await GetFolder("MyFolderName");
var fileName = $"{random}-{DateTime.Now.ToString("yyyyMMddHHmmss")}.xml";
var myFile = await myFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(myFile, "some content");

private static async Task<StorageFolder> GetFolder(string folderName)
{
    var storageFolder = ApplicationData.Current.LocalFolder;

    var possibleFolder = await storageFolder.TryGetItemAsync(folderName);
    if (possibleFolder == null)
    {
        await storageFolder.CreateFolderAsync(folderName);
    }

    var folder = await storageFolder.GetFolderAsync(folderName);

    return folder;
}

The exception is thrown on line await FileIO.WriteTextAsync(myFile, "some content"); with the following details

System.IO.FileLoadException: The process cannot access the file because it is being used by another process.

The file is in use. Please close the file before continuing. at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at MyClass.<>c__DisplayClass6_0.<b__0>d.MoveNext()

I really don't get, how can a brand new file being used already?

1

1 Answers

0
votes

I have tested your code in a blank project and it works perfectly fine.

May it be possible that you are calling this method from multiple threads at once? If yes, you should consider using a Semaphore or lock to prevent multiple threads from accessing the section at once.

Also, random may not be completely random. If you create multiple instances of the Random class at the same time, it is very possible that you will get the same values when first queried, because it is just pseudo-random. The best approach is to create just one, shared instance of the class.

Put together:

private static Random _randomizer = new Random();

public async Task CreateFileAsync()
{        
    var random = 0;
    lock ( _randomizer )
    {
       random = _randomizer.Next();
    }

    var myFolder = await GetFolder("MyFolderName");
    var fileName = $"{random}-{DateTime.Now.ToString("yyyyMMddHHmmss")}.xml";
    var myFile = await myFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
    await FileIO.WriteTextAsync(myFile, "some content");

    async Task<StorageFolder> GetFolder(string folderName)
    {
        var storageFolder = ApplicationData.Current.LocalFolder;

        var possibleFolder = await storageFolder.TryGetItemAsync(folderName);
        if (possibleFolder == null)
        {
            await storageFolder.CreateFolderAsync(folderName);
        }

        var folder = await storageFolder.GetFolderAsync(folderName);

        return folder;
    }            
}