这真的非常接近真正的方法Bob posted我们拥有的是与特定数据合并的模板。下面的代码试图重用我们已经构建的模板。所以如果我们已经为“达拉斯”建立了一个模板,我们可以重用它。我们看到的是“达拉斯”的模板,其中包含“纽约”模板应该具有的信息。当我们慢慢浏览代码时,我们看不到它。我的想法是,可变SC低于正被另一个线程改变了之前它被放到哈希表genericTemplates所以当线程与达拉斯信息工作是准备把信息插入到genericTemplaes哈希表的线程与纽约合作已经改变了保存在sc内的数据,以反映纽约数据,但加盖了达拉斯的“recordHash”密钥。像Bob一样,我对使用Lock语句并理解其真正的工作原理很陌生。C#多线程代码问题破坏数据
我还被告知,线程范围内的任何变量只与该线程有关。它只是全局变量或传入的对象,我需要查看。有人能证实这一点。
private Template EnsureGenericTemplate(Detail details, Hashtable genericTemplates)
{
Template return_Object = null;
SectionContainer sc = null;
StringBuilder htmlTemplate = null;
string recordHash = string.Format("{0}_{1}_{2}", circleNumber, zipCode, topicCd);
lock (genericTemplates) {
hasTemplateDefined = genericTemplates.ContainsKey(recordHash);
{
if (!hasTemplateDefined)
{
templateData = getTemplateData();
htmlTemplate = new StringBuilder(foo1.HtmlTemplate);
HtmlParser = hp = new HtmlParser();
sc = hp.parseNew(htmlTemplate.ToString(), false);
//This method merges the html template with the template data based on <tags>
htmlTemplate = BuildTemplate(sc, htmlTemplate.ToString(), templateData);
//This method merges the html template with the template data base on %SomeVar%
hp.parseProperties<Detail>(ref htmlTemplate, details, false);
//Puts the htmlTemplate into an object that hold html and text
foo2.Html = htmlTemplate.ToString();
lock (genericTemplates)
{
if (!genericTemplates.ContainsKey(recordHash))
{
return_Object = new Template(foo2, sc);
genericTemplates.Add(recordHash, Object_For_Reuse);
}
}
}
if (htmlTemplate == null)
{
lock (genericTemplates)
{
if (genericTemplates.ContainsKey(recordHash))
return_Object = (Template)genericTemplates[recordHash];
}
}
return return_Object;
}
一个对象,它是可能改变永远不要使用锁。如果您想正确使用锁,请创建一个仅用于锁的对象。这是一个常见的错误。 所以对象lockMe = new Object(); - 并确保其静态。 – Haedrian 2012-03-14 19:24:45
不确定您的示例是否包含足够的详细信息来发现问题。你似乎有3个锁定语句。在第一个之后,'hasTemplateDefined'可以设置为false,然后另一个线程可以定义模板,那么你当前的线程将进入由if(!hasTemplateDefined)'保护的块。我不知道这本身是否会造成问题,但守卫并不“安全”。 – Rob 2012-03-14 19:48:05