【发布时间】:2012-01-27 09:58:51
【问题描述】:
我有兴趣为我的函数调用计时数据库 + 其他函数来为我的应用程序的性能构建一些指标。我使用了 Stopwatch 和一个指标对象,但它似乎并没有始终如一地给出正确的值。有时调用一个函数所用的时间对于所有调用都是完全相同的,这是不现实的......
我发现问题的原因在于 Metrics 对象属性值。当其他线程生成的 Metrics 的其他实例被赋值时,一个 Metrics 对象的值会被覆盖。尽管每个线程都创建了一个新实例,但似乎属性值是每个引用的。
在多线程共享的对象中实现唯一性的最佳方法是什么?
代码如下:
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) =>
{
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);
}
}
});
任何帮助将不胜感激。 谢谢, 回复
【问题讨论】:
-
Metrics类是什么样的?
标签: c# concurrency parallel.foreach