Note that there are some explanatory texts on larger screens.

plurals
  1. PO What's the best approach to achieve uniqueness in an object shared by multiple threads?
    text
    copied!<p>I am interested in timing my function calls to database + other functions to build some metrics for my application's performance. I used Stopwatch and a metrics object, but it doesn't seem to consistently give correct values. Sometimes the elapsed time for calling a function is exactly the same for all the calls which is unrealistic...</p> <p>I have discovered that the reason for the problem is due to the Metrics object properties values. The values of one Metrics object get overwritten when other instances of the Metrics generated by other threads are assigned values. It seems like the properties values are per reference although a new instance is created by each thread. </p> <p>What's the best approach to achieve uniqueness in an object shared by multiple threads?</p> <p>Code below:</p> <pre><code>private Metrics Metrics; private Stopwatch Stopwatch; private int DegreeOfParallelism { get { return Convert.ToInt32(ConfigurationManager.AppSettings["DegreeOfParallelism"].ToString()); } } var lOptions = new ParallelOptions() { MaxDegreeOfParallelism = DegreeOfParallelism }; Parallel.ForEach(RequestBag, lOptions, (lItem, loopState) =&gt; { if (!string.IsNullOrEmpty(lItem.XmlRequest)) { try { Metrics = new Metrics(); Stopwatch = new Stopwatch(); Stopwatch.Start(); ObjRef = new Object(); lItem.XmlRequest = ObjRef.GetDecision(Username, Password); Stopwatch.Stop(); Metrics.ElapsedTime = string.Format("{0:0.00}", Stopwatch.Elapsed.TotalSeconds); Stopwatch.Restart(); if (!string.IsNullOrEmpty(DBConnectionString)) { DataAccess = new DataAccess2(DBConnectionString); DataAccess.WriteToDB(lItem.XmlRequest); } Stopwatch.Stop(); Metrics.DbFuncCallTime = string.Format("{0:0.00}", Stopwatch.Elapsed.TotalSeconds); } catch (Exception pEx) { KeepLog(pEx); Metrics.HasFailed = true; } finally { ProcessedIdsBag.Add(lItem.OrderId); Metrics.ProcessedOrderId = lItem.OrderId; Metrics.DegreeOfParallelism = DegreeOfParallelism; Metrics.TotalNumOfOrders = NumberOfOrders; Metrics.TotalNumOfOrdersProcessed = ProcessedIdsBag.Count; pBackgroundWorker.ReportProgress(Metrics.GetProgressPercentage(NumberOfOrders, ProcessedIdsBag.Count), Metrics); RequestBag.TryTake(out lItem); } } }); </code></pre> <p>Any help will be very much appreciated. Thanks, R</p>
 

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