我必须在我公司的 CRM 解决方案(Oracle's Right Now)中查询我们的 60 万用户,如果存在则更新它们,如果不存在则创建它们。要知道用户现在是否已经存在,我使用了第三方 WS。对于 60 万用户来说,这可能是一个真正的痛苦,因为每次获得响应都需要时间(大约 1 秒)。所以我设法将我的代码更改为使用Parallel.ForEach
,在 0.35 秒内查询每条记录,并将其添加List<User>
到要创建或要更新的记录中(现在有点愚蠢,所以我需要将它们分成 2 个列表和调用 2 个不同的 WS 方法)。
我的代码在多线程之前可以完美运行,但耗时太长。问题是我无法使批次过大,或者当我尝试通过 Web 服务更新或创建时出现超时。所以我一次向他们发送大约 500 条记录,当它运行关键代码部分时,它会执行很多次。
Parallel.ForEach(boDS.USERS.AsEnumerable(), new ParallelOptions { MaxDegreeOfParallelism = -1 }, row =>
{
...
user = null;
user = QueryUserById(row["USER_ID"].Trim());
if (user == null)
{
isUpdate = false;
gObject.ID = new ID();
}
else
{
isUpdate = true;
gObject.ID = user.ID;
}
... fill user attributes as generic fields ...
gObject.GenericFields = listGenericFields.ToArray();
if (isUpdate)
listUserUpdate.Add(gObject);
else
listUserCreate.Add(gObject);
if (i == batchSize - 1 || i == (boDS.USERS.Rows.Count - 1))
{
UpdateProcessingOptions upo = new UpdateProcessingOptions();
CreateProcessingOptions cpo = new CreateProcessingOptions();
upo.SuppressExternalEvents = false;
upo.SuppressRules = false;
cpo.SuppressExternalEvents = false;
cpo.SuppressRules = false;
RNObject[] results = null;
// <Critical_code>
if (listUserCreate.Count > 0)
{
results = _service.Create(_clientInfoHeader, listUserCreate.ToArray(), cpo);
}
if (listUserUpdate.Count > 0)
{
_service.Update(_clientInfoHeader, listUserUpdate.ToArray(), upo);
}
// </Critical_code>
listUserUpdate = new List<RNObject>();
listUserCreate = new List<RNObject>();
}
i++;
});
我考虑过使用lock
or mutex
,但这对我没有帮助,因为他们只会等待之后执行。我需要一些解决方案来仅在该部分代码的一个线程中执行一次。可能吗?任何人都可以分享一些光吗?
谢谢和亲切的问候,莱安德罗