会社の CRM ソリューション (Oracle's Right Now) で 60 万人のユーザーを照会し、存在する場合は更新するか、存在しない場合は作成する必要があります。ユーザーが Right Now に既に存在するかどうかを確認するために、サード パーティの 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
たが、後で実行されるのを待つだけなので、役に立ちません。コードの一部のスレッドで1回だけ実行するための解決策が必要です。出来ますか?誰かが光を共有できますか?
よろしくお願いします、 レアンドロ