2012-06-07 162 views
0

我有这样的一个类。以下代码是否线程安全

public abstract class HtmlObject<T> 
{ 

    public HtmlObject() {} 
    public HtmlObject(string id, string name, T value) 
    { 
     this.ID = id; 
     this.Name = name; 
     this.Value = value; 
    } 

    public string ID { get; set; } 
    public string Name { get; set; } 
    public T Value { get; set; } 

    public abstract string Build(); 
} 

用一个看起来像这样的具体实现。

public class HtmlRadio : HtmlObject<string> 
{ 
    private const string RadioHtml = "<input type='radio' name='{0}' value='{1}' {2} />{1}<br />"; 

    public bool Checked { get; set; } 

    public override string Build() 
    { 
     if (this.Checked) 
      return string.Format(HtmlRadio.RadioHtml, this.Name, this.Value, "checked='checked'"); 
     else 
      return string.Format(HtmlRadio.RadioHtml, this.Name, this.Value, string.Empty); 
    } 
} 

而我想知道的是,如果如果在线程的呼吁,Build()将是安全的。我的假设是它不会因为如果我采取以下一系列调用

HtmlRadio radio = new HtmlRadio(); 
radio.Checked = false; 
//Something could happen here? 
string result = radio.Build(); 

我的理解是,radio.Checked价值可能它被设置和调用Build(),这是正确的之间改变?如果是的话,如果我想要怎么修复这个问题呢?

+0

究竟是什么,你认为“可能发生在这里”? – Chris

+0

您在这里有顺序很重要的一系列操作。当命令*不重要时,线程是最好的。你将不得不做一些工作来确保'Build'在属性被设置后才被调用......这就像是根本没有对它进行线程化。 –

回答

5
IHtmlRadio radio = new HtmlRadio(); 
radio.Checked = false; 
//Something could happen here only if you give `radio` to another thread somehow. 
string result = radio.Build(); 

是另一个线程能否访问radio?如果不是,那么你很好。

另外,你害怕什么?如果选中从false更改为true或false,那么您真的关心吗?它不会炸毁 - 它会返回一个布尔值,而不是抛出异常。

编辑:不,它不是线程安全的,写的,另一个线程可能会改变CheckedValueName,其中没有一个在任何顺序任何方式得到保护。

+0

我想我假设我的这个对象的实例是跨多个线程全局声明的。 PS:我可能不在乎,我也没有看到这么做的一个很好的理由,我纯粹问过,因为它的某些事情使我的兴趣达到了顶峰,我无法回答。 –

+0

@Maxim,但这不是你在你的例子中显示的,看起来广播是在本地定义的,并且只能由同一个线程访问。 – Polyfun

2

一般来说,实例成员是而不是设计为线程安全的。您的代码与.NET Framework中的大多数类一样不安全。

除非你的类是专门为并发相关的场景设计的(例如System.Collections.Concurrent命名空间),否则你不应该担心使它成为线程安全的;这只会导致过度复杂和低效的实现。在适用的情况下,线程访问的同步应该是消费代码的责任。