避免竞争条件创建StorageFolder

本文关键字:创建 StorageFolder 条件 竞争 | 更新日期: 2023-09-27 17:51:26

我正在单元测试一个新的Win8 Store应用程序,并注意到一个我想要避免的竞争条件。所以我正在寻找一种方法来避免这种竞争条件。

我有一个类,当实例化调用一个方法,以确保它有一个本地的StorageFolder。我的单元测试只是实例化对象并测试文件夹是否存在。有时文件夹不是,有时它是,所以我认为这是一个竞争条件,因为CreateFolderAsync是异步的(显然)。

public class Class1
{
    StorageFolder _localFolder = null;
    public Class1()
    {
        _localFolder = ApplicationData.Current.LocalFolder;
        _setUpStorageFolders();
    }
    public StorageFolder _LocalFolder
    {
        get
        {
            return _localFolder;
        }
    }

    async void _setUpStorageFolders()
    {
        try
        {
            _localFolder = await _localFolder.CreateFolderAsync("TestFolder", CreationCollisionOption.FailIfExists);
        }
        catch (Exception)
        {
            throw;
        }
    }
}

我的单元测试是这样的:

 [TestMethod]
    public void _LocalFolder_Test()
    {
        Class1 ke = new Class1();

        // TODO: Fix Race Condition 
        StorageFolder folder = ke._LocalFolder;
        string folderName = folder.Name;
        Assert.IsTrue(folderName == "TestFolder");
    }

避免竞争条件创建StorageFolder

按照Iboshuizen的建议,我将同步执行此操作。这可以用async, taskawait来完成。这里有一个问题——设置不能在Class1的构造函数中完成,因为构造函数不支持async/await。因此,SetUpStorageFolders现在是公共的,并从测试方法中调用。

public class Class1
{
    StorageFolder _localFolder = null;
    public Class1()
    {
        _localFolder = ApplicationData.Current.LocalFolder;
                // call to setup removed here because constructors
                // do not support async/ await keywords
    }
    public StorageFolder _LocalFolder
    {
        get
        {
            return _localFolder;
        }
    }
      // now public... (note Task return type)
    async public Task SetUpStorageFolders()
    {
        try
        {
            _localFolder = await _localFolder.CreateFolderAsync("TestFolder", CreationCollisionOption.FailIfExists);
        }
        catch (Exception)
        {
            throw;
        }
    }
}
测试:

 // note the signature change here (async + Task)
 [TestMethod]
    async public Task _LocalFolder_Test()
    {
        Class1 ke = new Class1();
        // synchronous call to SetupStorageFolders - note the await
        await ke.SetUpStorageFolders();
        StorageFolder folder = ke._LocalFolder;
        string folderName = folder.Name;
        Assert.IsTrue(folderName == "TestFolder");
    }