複数のスレッドから取り込むことができる要求のキューを実装する必要があります。このキューが1000個の完了した要求よりも大きくなると、この要求はデータベースに格納されます。ここに私の実装です:ConcurrentQueueからchuncksを正しく消費する方法
public class RequestQueue
{
private static BlockingCollection<VerificationRequest> _queue = new BlockingCollection<VerificationRequest>();
private static ConcurrentQueue<VerificationRequest> _storageQueue = new ConcurrentQueue<VerificationRequest>();
private static volatile bool isLoading = false;
private static object _lock = new object();
public static void Launch()
{
Task.Factory.StartNew(execute);
}
public static void Add(VerificationRequest request)
{
_queue.Add(request);
}
public static void AddRange(List<VerificationRequest> requests)
{
Parallel.ForEach(requests, new ParallelOptions() {MaxDegreeOfParallelism = 3},
(request) => { _queue.Add(request); });
}
private static void execute()
{
Parallel.ForEach(_queue.GetConsumingEnumerable(), new ParallelOptions {MaxDegreeOfParallelism = 5}, EnqueueSaveRequest);
}
private static void EnqueueSaveRequest(VerificationRequest request)
{
_storageQueue.Enqueue(new RequestExecuter().ExecuteVerificationRequest(request));
if (_storageQueue.Count > 1000 && !isLoading)
{
lock (_lock)
{
if (_storageQueue.Count > 1000 && !isLoading)
{
isLoading = true;
var requestChunck = new List<VerificationRequest>();
VerificationRequest req;
for (var i = 0; i < 1000; i++)
{
if(_storageQueue.TryDequeue(out req))
requestChunck.Add(req);
}
new VerificationRequestRepository().InsertRange(requestChunck);
isLoading = false;
}
}
}
}
}
ロックとisLoadingなしでこれを実装する方法はありますか?
なぜロックを使用しないのですか?この場合、パフォーマンスに影響を与えないようです。 – Evk
私は同意しますが、もっと良い方法があるかもしれません。また、私はisLoadingで正しくロックを実装することを確信していません – xalz
なぜあなたは 'isLoading'を必要としますか?単純に削除すると何が変わるのですか? – zerkms