Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to improve performance on two thread accesing a collection of items concurrently
    text
    copied!<p>I'm implementing Producer/Consumer aproach on a .net project 3.5</p> <p><strong>There is only one producer and one consumer each running on its own thread</strong></p> <p>The <code>CheckOrderToProcess</code> method checks a table that match certain conditions and adds them to a list (Producer)</p> <p>The <code>bgOrdenes_DoWork</code> method takes each item on the list and performs some logic (Consumer)</p> <p>I want to avoid locking the whole list <code>lstOrderToProcessto</code> in order to improve performance, I tried to use <code>ConcurrentQueue</code> but I can not upgrade to .net 4.0 due to limitations that this is going to be used in projects that cannot be upgraded to 4.0 </p> <p>How can I change this implementation to improve perfomance ? I does not have to be a list as long as it can be shared between threads and I can add at the end and take the first element (Queue)</p> <pre><code>public class DatabaseCache : ICacheDB { private static List&lt;NotificacionOrdenes&gt; lstOrderToProcess; private static Object lockOrders; private static BackgroundWorker bgOrdenes; private static bool pendingOrders = false; private static Timer timerCheck; public DatabaseCache(string eventSourceName, bool monitorearOrderNotifications) { bgOrdenes = new BackgroundWorker(); bgOrdenes.DoWork += new DoWorkEventHandler(bgOrdenes_DoWork); lstOrderToProcess = new List&lt;NotificacionOrdenes&gt;(); lockOrders = new Object(); CheckOrderToProcess(); if (!bgOrdenes.IsBusy) { bgOrdenes.RunWorkerAsync(); } //execute CheckOrderToProcess periodically timerCheck = new Timer(2000); timerCheck.Elapsed += new ElapsedEventHandler(timerCheck_Elapsed); timerCheck.Enabled = true; timerCheck.AutoReset = true; } void timerCheck_Elapsed(object sender, ElapsedEventArgs e) { CheckOrderToProcess(); } private void CheckOrderToProcess() { DataSet ds; NotificacionOrdenes notif; ds = Data.GetOrderNotifications_ToProcess(); //if there is new info to process if ((ds != null) &amp;&amp; (ds.Tables[0].Rows.Count != 0)) { foreach (DataRow row in ds.Tables[0].Rows) { notif = new NotificacionOrdenes(); //fill NOTIF with info of each row lock (lockOrders) { lstOrderToProcess.Add(notif); } } pendingOrders = true; } } void bgOrdenes_DoWork(object sender, DoWorkEventArgs e) { NotificacionOrdenes notif; while (true) { if (pendingOrders) { lock (lockOrders) { notif = lstOrderToProcess[0]; lstOrderToProcess.RemoveAt(0); //check to see if there is any pending order pendingOrders = lstOrderToProcess.Any(); } //Execute rest of the logic } } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload