我正在使用以下代码来加速从COM对象中检索数据:
const string status = "Getting node displacements...";
int count;
int totalCount;
IEnumerable<ILoadCase> loadCases;
ConcurrentBag<NodeDisplacements> nodeDisplacements;
// Check if results are even available
if (!this.HasResults)
return null;
// Get node displacements
nodeDisplacements = new ConcurrentBag<NodeDisplacements>();
loadCases = this.LoadCases.Cast<ILoadCase>().Union(this.LoadCombinations.Cast<ILoadCase>()).Where(lc => lc.ID >= StartLoadCase && lc.ID <= EndLoadCase);
count = 0;
totalCount = this.Nodes.Count * loadCases.Count();
Parallel.ForEach(this.Nodes, (node) => {
Parallel.ForEach(loadCases, (loadCase) => {
nodeDisplacements.Add(this.GetNodeDisplacements(node, loadCase));
this.OnModelBuildStatusUpdate(new ModelBuildStatusUpdateEventArgs(status, Interlocked.Increment(ref count), totalCount));
});
});
目前,我正在通过命令提示符对此进行测试,然后跟进this.OnModelBuildStatusUpdate(...)
中触发的事件。
由于并行循环,事件会多次触发。为了避免命令提示符被"Getting node displacements..."
消息淹没,我尝试了这个:
private static string previouStatusMessage;
static void model_ModelBuildStatusUpdate(StaadModel sender, ModelBuildStatusUpdateEventArgs e)
{
if (string.IsNullOrEmpty(previouStatusMessage) || !previouStatusMessage.Equals(e.StatusMessage))
{
Console.WriteLine(e.StatusMessage);
previouStatusMessage = e.StatusMessage;
}
Console.Write("\r{0:0.00%}", e.ElementsProcessed / (double)e.TotalElementsToProcess);
}
仅显示第一个状态消息,但此时它会多次显示(每个外部循环线程一次?)。我成像我需要锁定一些东西,但我无法弄清楚是什么。
如果有人能告诉我如何正确地为此举办活动,我会很感激。
答案 0 :(得分:3)
您的处理程序不是线程安全的。试试这个:
private static string previouStatusMessage;
private static object lockObject = new object();
static void model_ModelBuildStatusUpdate(StaadModel sender, ModelBuildStatusUpdateEventArgs e)
{
lock (lockObject)
{
if (string.IsNullOrEmpty(previouStatusMessage) || !previouStatusMessage.Equals(e.StatusMessage))
{
Console.WriteLine(e.StatusMessage);
previouStatusMessage = e.StatusMessage;
}
}
Console.Write("\r{0:0.00%}", e.ElementsProcessed / (double)e.TotalElementsToProcess);
}