2012-06-07 3 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

У вас есть последовательность действий здесь, где порядок имеет значение. Threading лучше всего, когда заказ * не имеет значения. Вам нужно будет сделать некоторую работу, чтобы убедиться, что '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 или true на false, вам все равно? Он не взорвется - он вернет логическое, а не исключение.

Edit: Нет, это не поточно- как написано, другой поток может изменить Checked и Value и Name, ни один из которых защищены каким-либо образом в любом порядке.

+0

Я предполагаю, что я исхожу из того, что мой экземпляр этого объекта объявлен глобально по нескольким потокам. PS: Я, наверное, не забочусь, и я не вижу большой причины для этого, я просто спросил, потому что это то, что меня заинтересовало, и я не мог ответить. –

+0

@Maxim, но это не то, что вы показываете в своем примере, где, как представляется, радио определяется локально и к нему доступен только тот же поток. – Polyfun

2

В целом, членами экземпляра являются не, предназначенные для обеспечения поточности. Ваш код такой же небезопасный, как и большинство классов в .NET Framework.

Если ваш класс не разработан специально для сценариев, связанных с параллелизмом (например, для пространства имен System.Collections.Concurrent), не стоит беспокоиться о его потокобезопасности; это приведет лишь к чрезмерно сложной и неэффективной реализации. Синхронизация поточного доступа, где это применимо, должна отвечать за потребительский код.

Смежные вопросы