在MongoLab Sandbox中:在IMongoCollection上使用await <sometype> .UpdateOneAsync时偶尔会失败

时间:2016-06-04 11:22:14

标签: c# mongodb asynchronous async-await

使用MongoLab Sandbox:

使用这个课程:

class Block {
    ObjectId Id { get; set; }
    List<Item> ListOfItems;
}

我正在测试以下方法,只是在某些Item Block字段中添加并ListOfItems

async Task AddItem(Block block, Item item) {
    var updateDefinition = Builders<Block>.Update
        .AddToSet(b => b.ListOfItems, item);

    var result = await blocksCollection.UpdateOneAsync(
        b => b.BlockId == block.BlockId, updateDefinition);

    // however the synchronous version works:
    // var result = blocksCollection.UpdateOneAsync(
    //      b => b.BlockId == block.BlockId, updateDefinition).Result;

    if (result.ModifiedCount != 1)
        throw new DbException();
}

这是测试:

async Task AddItemsTest() {
    await Task.WhenAll(Enumerable.Range(0, 20).Select(
        i => AddItem(certainBlock, new Item())));
}

现在,如果我异步运行它(await方法上使用blocksCollection.UpdateOneAsync),有时result.ModifiedCount为0而不是1(大约1到17次),这会抛出{ {1}}。

当我同步运行它时(没有DbExceptionawait),一切正常,所有20个项目都被添加。

为什么?可能是.Result(mlab.com,最近......)对沙盒环境的限制吗?

2 个答案:

答案 0 :(得分:0)

试试这个

async Task AddItem(Block block, Item item) {
    var updateDefinition = Builders<Block>.Update
        .AddToSet(b => b.ListOfItems, item);

    var result = await blocksCollection.UpdateOneAsync(
        b => b.BlockId == block.BlockId, updateDefinition);
static object locker = new object();
    // however the synchronous version works:
    // var result = blocksCollection.UpdateOneAsync(
    //      b => b.BlockId == block.BlockId, updateDefinition).Result;
lock(locker)
   {
    if (result.ModifiedCount != 1)
        throw new DbException();
   }
}

答案 1 :(得分:0)

好像是MongoLab / mLab问题。当切换到Azure的DocumentDB(with same code btw, apparently they also support MongoDB now...)时,一切正常,没有代码更改......

我正在考虑现在该做什么,在他们的支持下开始乒乓球或只是放弃......