我正在使用C ++ / Cli来处理编译为dll的mongoDB最新C#驱动程序。我在C ++代码中使用了驱动程序的实例。
我已多次尝试过。如果我构建多个线程,每个线程都尝试更新同一个集合中的文档,那么似乎只有一个线程会成功。当我为线程设置休眠时间时,似乎工作正常。但我需要在短时间内同时更新数千个文件,设置睡眠时间不是一种有效的方法。
以下是线程的启动方式:
void updateKOOnMongo(int i, int k) {
time_t tn = time(NULL);
Sleep(max(1, (lastkoupdatetime - tn + 2) * 1000));
lastkoupdatetime = time(NULL);
MongoUpdates ^mgudt = gcnew MongoUpdates(i, k);
Thread ^updateko = gcnew Thread(gcnew ThreadStart(mgudt, &MongoUpdates::UpdateKO));
updateko->Start();
}
以下是MongoUpdates中的函数:
void MongoUpdates::UpdateKO {
mongoImp->updateKO(i, k);
}
mongoImp is an instance of the mongoDB C# driver compiled as dll.
以下是C#驱动程序中的代码:
public static async void updateKO(int i, int k)
{
await updateKOdr(i, k);
}
static async Task updateKOdr(int i, int k)
{
string col = "ko." + i.ToString();
var collection = _database.GetCollection<BsonDocument>(col);
var builder = Builders<BsonDocument>.Filter;
var filter = builder.Eq("a", i) & builder.Lte("lf", k);
var update = Builders<BsonDocument>.Update.Set("status", 0);
var result = await collection.UpdateOneAsync(filter, update);
}
如果删除以下部分:
time_t tn = time(NULL);
Sleep(max(1, (lastkoupdatetime - tn + 2) * 1000));
lastkoupdatetime = time(NULL);
如果两个或多个线程同时处理同一个集合,它几乎总是会失败。请帮忙。
答案 0 :(得分:0)
我发现问题是我在每次更新操作中都创建了一个新的集合实例。这很糟糕,我没注意到,因为代码是很久以前写的,当时我对mongoDB很新。 mongoDB集合是线程安全的,所以我应该在全局级别定义它:
protected static IMongoCollection<BsonDocument> _collection;
所以我可以使用它而不必每次都创建它的新实例。我只需要这样做:
if (_collection == null) {
_collection = _database.GetCollection<BsonDocument>("ko." + i.ToString());
}